PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
Subsystems (6)
v2 cover 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.
This patchset is based on v4.1-rc1.
Change from RFC v1:
1. Add 1/4 patch by Arnd which removes align_resource callback in ARM pcibios_align_resource.
2. Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
3. Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape, spear13xx.
4. Remove unnecessary parentheses of some macros in pcie-hisi.
5. Use macro to replace some magic values.
6. Merge two loops together and add some comments about it in context_config function in pcie-hisi.
7. Modify some value of items in pcie node example in binding document.
Change from RFC:
1. 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 RFC v1:
- http://www.spinics.net/lists/linux-pci/msg41305.html
Link of RFC:
- http://www.spinics.net/lists/linux-pci/msg40434.html
Zhou Wang (4):
ARM/PCI: remove align_resource callback in pcibios_align_resource
PCI: designware: Add ARM64 support
PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
Documentation: DT: Add Hisilicon PCIe host binding
.../devicetree/bindings/pci/hisilicon-pcie.txt | 46 ++++ arch/arm/kernel/bios32.c | 4 - drivers/pci/host/Kconfig | 5 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pci-mvebu.c | 47 ++-- drivers/pci/host/pcie-designware.c | 128 ++++------ drivers/pci/host/pcie-hisi.c | 258 +++++++++++++++++++++ drivers/pci/host/pcie-spear13xx.c | 2 +- drivers/pci/setup-res.c | 27 ++- include/linux/pci.h | 3 + 15 files changed, 421 insertions(+), 109 deletions(-) create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt create mode 100644 drivers/pci/host/pcie-hisi.c
Signature · 1 line
1.9.1
PATCH v2 1/4 ARM/PCI: remove align_resource callback in pcibios_align_resource
This patch had added by Arnd Bergmann during last reviewing of v1 patchset[1].
PCI core codes call pcibios_align_resource(). In ARM specific one, it will dereference pci_sys_data and call sys->align_resource. If we try to unify ARM and ARM64 PCIe API in pcie-designware. it will bring kernel crash when run into this dereferencing.
However, in ARM there is only pci-mvebu which implements align_resource. So add align_resource call back in pci_host_bridge structure and override pcibios_align_resource with it.
[1] http://www.spinics.net/lists/linux-pci/msg41671.html
--- arch/arm/kernel/bios32.c | 4 ---- drivers/pci/host/pci-mvebu.c | 47 ++++++++++++++++++++++++++++---------------- drivers/pci/setup-res.c | 27 ++++++++++++++++++++----- include/linux/pci.h | 3 +++ 4 files changed, 55 insertions(+), 26 deletions(-)
arch/arm/kernel/bios32.c +0 -4
@@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; - sys->align_resource = hw->align_resource;INIT_LIST_HEAD (&sys->resources);if (hw->private_data)
@@ -597,9 +596,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, start = (start + align -1 ) & ~(align -1 ); -if (sys->align_resource) -return sys->align_resource (dev, res, start, size, align); -return start; }
drivers/pci/host/pci-mvebu.c +30 -17
76 lines not on this page · raw message
drivers/pci/setup-res.c +22 -5
@@ -200,7 +200,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, }static int __pci_assign_resource (struct pci_bus *bus,struct pci_dev *dev, -int resno,resource_size_t size,resource_size_t align) +int resno,resource_size_t size,resource_size_t align, +resource_size_t (*alignf)(void *, +const struct resource *, +resource_size_t , +resource_size_t )) {struct resource *res = dev->resource + resno;resource_size_t min;
@@ -217,7 +221,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,*/ ret =pci_bus_alloc_resource (bus, res, size, align, min,IORESOURCE_PREFETCH |IORESOURCE_MEM_64 , - pcibios_align_resource, dev); + alignf, dev);if (ret ==0 )return 0 ;
@@ -229,7 +233,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) { ret =pci_bus_alloc_resource (bus, res, size, align, min,IORESOURCE_PREFETCH , - pcibios_align_resource, dev); + alignf, dev);if (ret ==0 )return 0 ; }
@@ -242,7 +246,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,*/ if (res->flags & (IORESOURCE_PREFETCH |IORESOURCE_MEM_64 )) ret =pci_bus_alloc_resource (bus, res, size, align, min,0 , - pcibios_align_resource, dev); + alignf, dev);return ret; }
@@ -251,10 +255,23 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, resource_size_t size, resource_size_t min_align) {struct pci_bus *bus; +struct pci_host_bridge *phb; +resource_size_t (*alignf)(void *, +const struct resource *, +resource_size_t , +resource_size_t );int ret; bus = dev->bus; -while ((ret =__pci_assign_resource (bus, dev, resno, size, min_align))) { + phb =pci_find_host_bridge (bus); + +if (phb->align_resource) + alignf = phb->align_resource; +else + alignf = pcibios_align_resource; + +while ((ret =__pci_assign_resource (bus, dev, resno, size, + min_align, alignf))) {if (!bus->parent || !bus->self->transparent)break ; bus = bus->parent;
include/linux/pci.h +3 -0
@@ -404,6 +404,9 @@ struct pci_host_bridge {struct device dev;struct pci_bus *bus;/* root bus */ struct list_head windows;/* resource_entry */ +resource_size_t (*align_resource)(void *data, +const struct resource *res, +resource_size_t size,resource_size_t align);void (*release_fn)(struct pci_host_bridge *);void *release_data; unsigned int ignore_reset_delay:1; /* for entire hierarchy */
Signature · 1 line
1.9.1
PATCH v2 1/4 ARM/PCI: remove align_resource callback in pcibios_align_resource
Quoted 13 lines · Zhou Wang
arch/arm/kernel/bios32.c +0
-1@@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; - sys->align_resource = hw->align_resource;INIT_LIST_HEAD (&sys->resources);if (hw->private_data)
arch/arm/kernel/bios32.c resource_size_t pcibios_align_resource(void *data, const struct resource *res, · line 600
Quoted 8 lines
arch/arm/kernel/bios32.c +0
-3@@ -597,9 +596,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, start = (start + align -1 ) & ~(align -1 ); -if (sys->align_resource) -return sys->align_resource (dev, res, start, size, align); -return start; }
This leaves both 'sys' and 'dev' in this function as unused variables. Please remove them too.
drivers/pci/host/pci-mvebu.c line 26
Quoted 10 lines
drivers/pci/host/pci-mvebu.c +2
-0@@ -22,6 +22,8 @@#include <linux/of_pci.h> #include <linux/of_platform.h> +#include "../pci.h" /* HACK to see pci_find_host_bridge */ +
Wouldn't it be better to promote pci_find_host_bridge to be declared in include/linux/pci.h instead?
Thanks,
James
Quoted 74 lines
drivers/pci/host/pci-mvebu.c +28
-17/* * PCIe unit register offsets. */ @@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)return 1 ; } -static struct pci_bus *mvebu_pcie_scan_bus (int nr,struct pci_sys_data *sys) +static resource_size_t mvebu_pcie_align_resource (void *data, +const struct resource *res, +resource_size_t size, +resource_size_t align) { -struct mvebu_pcie *pcie =sys_to_pcie (sys); -struct pci_bus *bus; +struct pci_dev *dev = data; - bus =pci_create_root_bus (&pcie->pdev->dev, sys->busnr, - &mvebu_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; +resource_size_t start = res->start; -pci_scan_child_bus (bus); +if (res->flags &IORESOURCE_IO && start &0x300 ) + start = (start +0x3ff ) & ~0x3ff ; -return bus; -} + start = (start + align -1 ) & ~(align -1 ); -static resource_size_t mvebu_pcie_align_resource (struct pci_dev *dev, -const struct resource *res, -resource_size_t start, -resource_size_t size, -resource_size_t align) -{if (dev->bus->number !=0 )return start;@@ -796,6 +791,25 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,return start; } +static struct pci_bus *mvebu_pcie_scan_bus (int nr,struct pci_sys_data *sys) +{ +struct mvebu_pcie *pcie =sys_to_pcie (sys); +struct pci_host_bridge *phb; +struct pci_bus *bus; + + bus =pci_create_root_bus (&pcie->pdev->dev, sys->busnr, + &mvebu_pcie_ops, sys, &sys->resources); +if (!bus) +return NULL ; + + phb =pci_find_host_bridge (bus); + phb->align_resource = mvebu_pcie_align_resource; + +pci_scan_child_bus (bus); + +return bus; +} +static void mvebu_pcie_enable (struct mvebu_pcie *pcie) {struct hw_pci hw;@@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie) hw.scan = mvebu_pcie_scan_bus; hw.map_irq = of_irq_parse_and_map_pci; hw.ops = &mvebu_pcie_ops; - hw.align_resource = mvebu_pcie_align_resource;pci_common_init (&hw); }
PATCH v2 1/4 ARM/PCI: remove align_resource callback in pcibios_align_resource
Quoted 17 lines · James Morse
Quoted 16 lines · Zhou Wang
arch/arm/kernel/bios32.c +0
-1@@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; - sys->align_resource = hw->align_resource;INIT_LIST_HEAD (&sys->resources);if (hw->private_data)@@ -597,9 +596,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, start = (start + align -1 ) & ~(align -1 );
Quoted 9 lines
arch/arm/kernel/bios32.c resource_size_t pcibios_align_resource(void *data, const struct resource *res, · line 600
Quoted 5 lines
arch/arm/kernel/bios32.c +0
-3-if (sys->align_resource) -return sys->align_resource (dev, res, start, size, align); -return start; }This leaves both 'sys' and 'dev' in this function as unused variables. Please remove them too.
Right, will do in next version.
Quoted 15 lines
drivers/pci/host/pci-mvebu.c line 26
Quoted 10 lines
drivers/pci/host/pci-mvebu.c +2
-0@@ -22,6 +22,8 @@#include <linux/of_pci.h> #include <linux/of_platform.h> +#include "../pci.h" /* HACK to see pci_find_host_bridge */ +Wouldn't it be better to promote
pci_find_host_bridgeto be declared ininclude/linux/pci.hinstead?
Quoted 4 lines
Thanks,
James
The files which use pci_find_host_bridge are all under drivers/pci, so maybe putting in drivers/pci/pci.h is better ?
Many thanks for reviewing?
Zhou
Quoted 78 lines
Quoted 67 lines
drivers/pci/host/pci-mvebu.c +28
-16/* * PCIe unit register offsets. */ @@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)return 1 ; } -static struct pci_bus *mvebu_pcie_scan_bus (int nr,struct pci_sys_data *sys) +static resource_size_t mvebu_pcie_align_resource (void *data, +const struct resource *res, +resource_size_t size, +resource_size_t align) { -struct mvebu_pcie *pcie =sys_to_pcie (sys); -struct pci_bus *bus; +struct pci_dev *dev = data; - bus =pci_create_root_bus (&pcie->pdev->dev, sys->busnr, - &mvebu_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; +resource_size_t start = res->start; -pci_scan_child_bus (bus); +if (res->flags &IORESOURCE_IO && start &0x300 ) + start = (start +0x3ff ) & ~0x3ff ; -return bus; -} + start = (start + align -1 ) & ~(align -1 ); -static resource_size_t mvebu_pcie_align_resource (struct pci_dev *dev, -const struct resource *res, -resource_size_t start, -resource_size_t size, -resource_size_t align) -{if (dev->bus->number !=0 )return start;@@ -796,6 +791,25 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,return start; } +static struct pci_bus *mvebu_pcie_scan_bus (int nr,struct pci_sys_data *sys) +{ +struct mvebu_pcie *pcie =sys_to_pcie (sys); +struct pci_host_bridge *phb; +struct pci_bus *bus; + + bus =pci_create_root_bus (&pcie->pdev->dev, sys->busnr, + &mvebu_pcie_ops, sys, &sys->resources); +if (!bus) +return NULL ; + + phb =pci_find_host_bridge (bus); + phb->align_resource = mvebu_pcie_align_resource; + +pci_scan_child_bus (bus); + +return bus; +} +static void mvebu_pcie_enable (struct mvebu_pcie *pcie) {struct hw_pci hw;drivers/pci/host/pci-mvebu.c static void mvebu_pcie_enable(struct mvebu_pcie *pcie) · line 831
Quoted 7 lines
drivers/pci/host/pci-mvebu.c +0
-1@@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie) hw.scan = mvebu_pcie_scan_bus; hw.map_irq = of_irq_parse_and_map_pci; hw.ops = &mvebu_pcie_ops; - hw.align_resource = mvebu_pcie_align_resource;pci_common_init (&hw); }.
PATCH v2 2/4 PCI: designware: Add ARM64 support
In reply to Zhou WangThis patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci, move related operations to dw_pcie_host_init. Also set pp->root_bus_nr = 0 in each PCIe host driver which is based on pcie-designware.
I am not very clear about I/O resource management:
Quoted 6 lines
if (global_io_offset < SZ_1M && pp->io_size > 0) {
pci_ioremap_io(global_io_offset, pp->io_base);
global_io_offset += SZ_64K;
pci_add_resource_offset(&res, &pp->io,
global_io_offset - pp->io_bus_addr);
}so just move steps in dw_pcie_setup to dw_pcie_host_init.
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.
--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 128 +++++++++++++++---------------------- drivers/pci/host/pcie-spear13xx.c | 2 +- 7 files changed, 56 insertions(+), 83 deletions(-)
drivers/pci/host/pci-dra7xx.c +1 -0
@@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, pp = &dra7xx->pp; pp->dev = dev; + pp->root_bus_nr =0 ; pp->ops = &dra7xx_pcie_host_ops; pp->irq =platform_get_irq (pdev,1 );
drivers/pci/host/pci-exynos.c +1 -1
@@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &exynos_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pci-imx6.c +1 -1
@@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &imx6_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pci-keystone.c +1 -1
@@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &keystone_pcie_host_ops; ret =ks_dw_pcie_host_init (ks_pcie, ks_pcie->msi_intc_np);if (ret) {
drivers/pci/host/pci-layerscape.c +1 -1
@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pcie-designware.c +50 -78
200 lines not on this page · raw message
drivers/pci/host/pcie-spear13xx.c +1 -1
@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp);
Signature · 1 line
1.9.1
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 12 lines · 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_irqand structhw_pci, move related operations todw_pcie_host_init. Also setpp->root_bus_nr= 0 in each PCIe host driver which is based on pcie-designware.I am not very clear about I/O resource management:
Quoted 6 lines
if (global_io_offset < SZ_1M && pp->io_size > 0) { pci_ioremap_io(global_io_offset, pp->io_base); global_io_offset += SZ_64K; pci_add_resource_offset(&res, &pp->io, global_io_offset - pp->io_bus_addr); }
Quoted 5 lines
so just move steps in
dw_pcie_setuptodw_pcie_host_init.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.
I have tested this on a 'Freescale i.MX6 Quad SABRE Lite Board', which also uses a designware pcie host controller (PCI_IMX6). Booted, removed/rescanned the bus, then scanned for wireless access points using the b43 driver. Please note my change below.
Quoted 87 lines
drivers/pci/host/pcie-designware.c +13
-15@@ -11,6 +11,7 @@* published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -67,17 +68,10 @@#define PCIE_ATU_FUNC (x) (((x) & 0x7) << 16)#define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; +static struct pci_ops dw_pcie_ops;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; -} -int dw_pcie_cfg_read (void __iomem *addr,int where,int size,u32 *val) { *val =readl (addr);@@ -238,7 +232,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)static int assign_irq (int no_irqs,struct msi_desc *desc,int *pos) {int irq, pos0, i; -struct pcie_port *pp =sys_to_pcie (desc->dev->bus->sysdata); +struct pcie_port *pp = desc->dev->bus->sysdata; pos0 =bitmap_find_free_region (pp->msi_irq_in_use,MAX_MSI_IRQS ,order_base_2 (no_irqs));@@ -281,7 +275,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, {int irq, pos;struct msi_msg msg; -struct pcie_port *pp =sys_to_pcie (pdev->bus->sysdata); +struct pcie_port *pp = pdev->bus->sysdata;if (desc->msi_attrib.is_msix)return -EINVAL ;@@ -310,7 +304,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) {struct irq_data *data =irq_get_irq_data (irq);struct msi_desc *msi =irq_data_get_msi (data); -struct pcie_port *pp =sys_to_pcie (msi->dev->bus->sysdata); +struct pcie_port *pp = msi->dev->bus->sysdata;clear_irq_range (pp, irq,1 , data->hwirq); }@@ -342,13 +336,15 @@ static const struct irq_domain_ops msi_domain_ops = { .map = dw_pcie_msi_map, }; -int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ 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 - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 515
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn);
I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the below arm64 code.
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 2 lines
drivers/pci/host/pcie-designware.c +2
-0+#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base);
of_pci_get_host_bridge_resources expects &pp->io_base to be a resource_size_t*, but &io_base is u64*. This generates a warning on arm with the above change. Changing the the type in drivers/pci/host/pcie-designware.h fixes this.
Thanks,
James
Quoted 115 lines
drivers/pci/host/pcie-designware.c +25
-63+if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +707,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; -pci_add_resource_offset (&sys->resources, &pp->mem, sys->mem_offset); -pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus (int nr,struct pci_sys_data *sys) -{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pcie_port *pp =sys_to_pcie (dev->bus->sysdata); -int irq; - - irq =of_irq_parse_and_map_pci (dev, slot, pin); -if (!irq) - irq = pp->irq; - -return irq; -} - -static struct hw_pci dw_pci = { - .setup = dw_pcie_setup, - .scan = dw_pcie_scan_bus, - .map_irq = dw_pcie_map_irq, -}; -void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 19 lines · James Morse
Quoted 12 lines · 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_irqand structhw_pci, move related operations todw_pcie_host_init. Also setpp->root_bus_nr= 0 in each PCIe host driver which is based on pcie-designware.I am not very clear about I/O resource management:
Quoted 6 lines
if (global_io_offset < SZ_1M && pp->io_size > 0) { pci_ioremap_io(global_io_offset, pp->io_base); global_io_offset += SZ_64K; pci_add_resource_offset(&res, &pp->io, global_io_offset - pp->io_bus_addr); }Quoted 5 lines
so just move steps in
dw_pcie_setuptodw_pcie_host_init.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.
Quoted 7 lines
I have tested this on a 'Freescale i.MX6 Quad SABRE Lite Board', which also uses a designware pcie host controller (
PCI_IMX6). Booted, removed/rescanned the bus, then scanned for wireless access points using the b43 driver. Please note my change below.Tested-by James Morse <[email protected]>
Hi James,
Many thanks for your help to test :)
Quoted 101 lines
Quoted 87 lines
drivers/pci/host/pcie-designware.c +13
-15@@ -11,6 +11,7 @@* published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -67,17 +68,10 @@#define PCIE_ATU_FUNC (x) (((x) & 0x7) << 16)#define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; +static struct pci_ops dw_pcie_ops;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; -} -int dw_pcie_cfg_read (void __iomem *addr,int where,int size,u32 *val) { *val =readl (addr);@@ -238,7 +232,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)static int assign_irq (int no_irqs,struct msi_desc *desc,int *pos) {int irq, pos0, i; -struct pcie_port *pp =sys_to_pcie (desc->dev->bus->sysdata); +struct pcie_port *pp = desc->dev->bus->sysdata; pos0 =bitmap_find_free_region (pp->msi_irq_in_use,MAX_MSI_IRQS ,order_base_2 (no_irqs));@@ -281,7 +275,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, {int irq, pos;struct msi_msg msg; -struct pcie_port *pp =sys_to_pcie (pdev->bus->sysdata); +struct pcie_port *pp = pdev->bus->sysdata;if (desc->msi_attrib.is_msix)return -EINVAL ;@@ -310,7 +304,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) {struct irq_data *data =irq_get_irq_data (irq);struct msi_desc *msi =irq_data_get_msi (data); -struct pcie_port *pp =sys_to_pcie (msi->dev->bus->sysdata); +struct pcie_port *pp = msi->dev->bus->sysdata;clear_irq_range (pp, irq,1 , data->hwirq); }@@ -342,13 +336,15 @@ static const struct irq_domain_ops msi_domain_ops = { .map = dw_pcie_msi_map, }; -int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ 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 - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 515
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the below arm64 code.
Quoted 3 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use a PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O Bar.
Quoted 9 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 2 lines
drivers/pci/host/pcie-designware.c +2
-0+#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warning on arm with the above change. Changing the the type indrivers/pci/host/pcie-designware.hfixes this.
Quoted 4 lines
Thanks,
James
OK, will modify this in next version.
Best Regards and thanks again for your test,
Zhou
Quoted 119 lines
Quoted 105 lines
drivers/pci/host/pcie-designware.c +25
-56+if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +707,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; -pci_add_resource_offset (&sys->resources, &pp->mem, sys->mem_offset); -pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus (int nr,struct pci_sys_data *sys) -{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pcie_port *pp =sys_to_pcie (dev->bus->sysdata); -int irq; - - irq =of_irq_parse_and_map_pci (dev, slot, pin); -if (!irq) - irq = pp->irq; - -return irq; -}drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 736
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7- -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;.
PATCH v2 2/4 PCI: designware: Add ARM64 support
On Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 39 lines
Quoted 39 lines
Quoted 25 lines
drivers/pci/host/pcie-designware.c +8
-4-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ 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 - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 515
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the below arm64 code.
Quoted 7 lines
Quoted 3 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use a PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O Bar.
There are two problems here:
1) the io_base address you get from of_pci_get_host_bridge_resources must be mapped using pci_remap_iospace. You are not doing this, so even if you had a PCIe card with I/O bar it would not work on arm64 as the code stands. Remember that I/O space on arm/arm64 works as a memory access with offset from PCI_IOBASE and that's the value you get in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c
2) (1) above would sort out I/O space access for both arm and arm64 so, as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
Lorenzo
Quoted 146 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 3 lines
drivers/pci/host/pcie-designware.c +2
-0+#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warning on arm with the above change. Changing the the type indrivers/pci/host/pcie-designware.hfixes this.Quoted 4 lines
Thanks,
James
OK, will modify this in next version.
Best Regards and thanks again for your test,
ZhouQuoted 110 lines
Quoted 110 lines
drivers/pci/host/pcie-designware.c +25
-61+if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +707,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; -pci_add_resource_offset (&sys->resources, &pp->mem, sys->mem_offset); -pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus (int nr,struct pci_sys_data *sys) -{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pcie_port *pp =sys_to_pcie (dev->bus->sysdata); -int irq; - - irq =of_irq_parse_and_map_pci (dev, slot, pin); -if (!irq) - irq = pp->irq; - -return irq; -} - -static struct hw_pci dw_pci = { - .setup = dw_pcie_setup, - .scan = dw_pcie_scan_bus, - .map_irq = dw_pcie_map_irq,Quoted 9 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 736
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-2-}; -void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;.
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/4 PCI: designware: Add ARM64 support
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I have removed the parser and now I use "of_pci_get_host_bridge_resources" in order to retrieve the resources associated to each pci host bridge window. The resources now are not copied to the designware pcie_port pp, instead they are passed by pointer.
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I have also included all the changes about the other drivers
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------
This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.
The intention is to complete the unification between ARM and ARM64 now that the dependency on arch/arm/kernel/bios32.c is gone.
I have also included the rework asked by James Morse:io_base declared as resource_size_t
It compiles fine on ARCH arm and arm64.
It needs to be tested.
--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 242 +++++++++++++++---------------------- drivers/pci/host/pcie-designware.h | 10 +- drivers/pci/host/pcie-spear13xx.c | 2 +- 8 files changed, 109 insertions(+), 154 deletions(-)
drivers/pci/host/pci-dra7xx.c +1 -0
@@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, pp = &dra7xx->pp; pp->dev = dev; + pp->root_bus_nr =0 ; pp->ops = &dra7xx_pcie_host_ops; pp->irq =platform_get_irq (pdev,1 );
drivers/pci/host/pci-exynos.c +1 -1
@@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &exynos_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pci-imx6.c +1 -1
@@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &imx6_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pci-keystone.c +1 -1
@@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &keystone_pcie_host_ops; ret =ks_dw_pcie_host_init (ks_pcie, ks_pcie->msi_intc_np);if (ret) {
drivers/pci/host/pci-layerscape.c +1 -1
@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pcie-designware.c +2 -10
@@ -11,6 +11,7 @@* published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h>
@@ -67,16 +68,7 @@#define PCIE_ATU_FUNC (x) (((x) & 0x7) << 16)#define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; - -static unsigned long global_io_offset; - -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) -{ -BUG_ON (!sys->private_data); - -return sys->private_data; -} +static struct pci_ops dw_pcie_ops; int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val) { @@ -238,7 +230,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) {int irq, pos0, i; -struct pcie_port *pp =sys_to_pcie (desc->dev->bus->sysdata);
+ struct pcie_port *pp = desc->dev->bus->sysdata;
pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
order_base_2(no_irqs));
@@ -281,7 +273,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, {
int irq, pos;
struct msi_msg msg;
- struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+ struct pcie_port *pp = pdev->bus->sysdata;
if (desc->msi_attrib.is_msix)
return -EINVAL;
@@ -310,7 +302,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) {
struct irq_data *data = irq_get_irq_data(irq);
struct msi_desc *msi = irq_data_get_msi(data);
- struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+ struct pcie_port *pp = msi->dev->bus->sysdata;
clear_irq_range(pp, irq, 1, data->hwirq); } @@ -342,16 +334,24 @@ static const struct irq_domain_ops msi_domain_ops = { .map = dw_pcie_msi_map,
};
-int dw_pcie_host_init(struct pcie_port *pp)
+int __init dw_pcie_host_init(struct pcie_port *pp)
{
struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev);
- struct of_pci_range range;
- struct of_pci_range_parser parser;
+ struct pci_bus *bus;
struct resource *cfg_res;
+ LIST_HEAD(res);
u32 val, na, ns;
const __be32 *addrp;
int i, index, ret;
+ int rlen;
+ struct pci_host_bridge_window *win;
+ const __be32 *parser_range_end = of_get_property(np, "ranges", &rlen);
+
+ if (parser_range_end == NULL)
+ return -ENOENT;
+ parser_range_end += rlen/sizeof(__be32);
+
/* Find the address cell size and the number of cells in order to get
* the untranslated address.
@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)
dev_err(pp->dev, "missing *config* reg space\n");
}
- if (of_pci_range_parser_init(&parser, np)) {
- dev_err(pp->dev, "missing ranges property\n");
- return -EINVAL;
- }
+ ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+ if (ret)
+ return ret;
/* Get the I/O and memory ranges from DT */
- for_each_of_pci_range(&parser, &range) {
- unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
- if (restype == IORESOURCE_IO) {
- of_pci_range_to_resource(&range, np, &pp->io);
- pp->io.name = "I/O";
- pp->io.start = max_t(resource_size_t,
- PCIBIOS_MIN_IO,
- range.pci_addr + global_io_offset);
- pp->io.end = min_t(resource_size_t,
- IO_SPACE_LIMIT, - range.pci_addr + range.size - + global_io_offset - 1);
- pp->io_size = resource_size(&pp->io);
- pp->io_bus_addr = range.pci_addr;
- pp->io_base = range.cpu_addr;
-
- /* Find the untranslated IO space address */
- pp->io_mod_base = of_read_number(parser.range -
- parser.np + na, ns);
- }
- if (restype == IORESOURCE_MEM) {
- of_pci_range_to_resource(&range, np, &pp->mem);
- pp->mem.name = "MEM";
- pp->mem_size = resource_size(&pp->mem);
- pp->mem_bus_addr = range.pci_addr;
-
- /* Find the untranslated MEM space address */
- pp->mem_mod_base = of_read_number(parser.range -
- parser.np + na, ns);
- }
- if (restype == 0) {
- of_pci_range_to_resource(&range, np, &pp->cfg);
- pp->cfg0_size = resource_size(&pp->cfg)/2;
- pp->cfg1_size = resource_size(&pp->cfg)/2;
- pp->cfg0_base = pp->cfg.start;
- pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
+ list_for_each_entry(win, &res, list) {
+ switch (resource_type(win->res)) {
+ case IORESOURCE_IO:
+ pp->io = win->res;
+ pp->io->name = "I/O";
+ pp->io_size = resource_size(pp->io);
+ pp->io_bus_addr = pp->io->start - win->offset;
+ /* magic 5 below comes from magic na and ns in
+ * of_pci_range_parser_init() */
+ pp->io_mod_base = of_read_number(parser_range_end -
+ of_n_addr_cells(np) - 5 + na, ns);
+ ret = pci_remap_iospace(pp->io, pp->io_base);
+ if (ret) {
+ dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+ ret, pp->io);
+ continue;
+ }
+ break;
+ case IORESOURCE_MEM:
+ pp->mem = win->res;
+ pp->mem->name = "MEM";
+ pp->mem_size = resource_size(pp->mem);
+ pp->mem_bus_addr = pp->mem->start - win->offset;
+ pp->mem_mod_base = of_read_number(parser_range_end -
+ of_n_addr_cells(np) - 5 + na, ns);
+ break;
+ case 0:
+ pp->cfg = win->res;
+ pp->cfg0_size = resource_size(pp->cfg)/2;
+ pp->cfg1_size = resource_size(pp->cfg)/2;
+ pp->cfg0_base = pp->cfg->start;
+ pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
/* Find the untranslated configuration space address */
- pp->cfg0_mod_base = of_read_number(parser.range -
- parser.np + na, ns);
- pp->cfg1_mod_base = pp->cfg0_mod_base +
- pp->cfg0_size;
+ pp->cfg0_mod_base = of_read_number(parser_range_end -
+ of_n_addr_cells(np) - 5 + na, ns);
+ pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
+ break;
+ case IORESOURCE_BUS:
+ pp->busn = win->res;
+ break;
+ default:
+ continue;
}
}
- ret = of_pci_parse_bus_range(np, &pp->busn);
- if (ret < 0) {
- pp->busn.name = np->name;
- pp->busn.start = 0;
- pp->busn.end = 0xff;
- pp->busn.flags = IORESOURCE_BUS;
- dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
- ret, &pp->busn);
- }
-
if (!pp->dbi_base) {
- pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
- resource_size(&pp->cfg));
+ pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+ resource_size(pp->cfg));
if (!pp->dbi_base) {
dev_err(pp->dev, "error with ioremap\n"); return -ENOMEM;
}
}
- pp->mem_base = pp->mem.start;
+ pp->mem_base = pp->mem->start;
if (!pp->va_cfg0_base) {
pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, @@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)
if (pp->ops->host_init)
pp->ops->host_init(pp);
- dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+ if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)
+ != PCIBIOS_SUCCESSFUL)
+ return -EINVAL;
/* program correct class for RC */
- dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
+ if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI)
+ != PCIBIOS_SUCCESSFUL)
+ return -EINVAL;
+
+ if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val)
+ != PCIBIOS_SUCCESSFUL)
+ return -EINVAL;
- dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
val |= PORT_LOGIC_SPEED_CHANGE;
- dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
-#ifdef CONFIG_PCI_MSI
- dw_pcie_msi_chip.dev = pp->dev;
- dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+ if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val)
+ != PCIBIOS_SUCCESSFUL)
+ return -EINVAL;
+
+ bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
+ pp, &res);
+ if (!bus)
+ return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+ bus->msi = container_of(&pp->irq_domain, struct msi_controller,
+domain); #else
+ bus->msi = &dw_pcie_msi_chip;
#endif
- dw_pci.nr_controllers = 1;
- dw_pci.private_data = (void **)&pp;
+ pci_scan_child_bus(bus);
+ if (pp->ops->scan_bus)
+ pp->ops->scan_bus(pp);
- pci_common_init_dev(pp->dev, &dw_pci);
+#ifdef CONFIG_ARM
+ /* support old dtbs that incorrectly describe IRQs */
+ pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); #endif
+
+ pci_assign_unassigned_bus_resources(bus);
+ pci_bus_add_devices(bus);
return 0;
}
@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp, static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
- struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+ struct pcie_port *pp = bus->sysdata;
int ret;
if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
- struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+ struct pcie_port *pp = bus->sysdata;
int ret;
if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf,
};
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{
- struct pcie_port *pp;
-
- pp = sys_to_pcie(sys);
-
- if (global_io_offset < SZ_1M && pp->io_size > 0) {
- sys->io_offset = global_io_offset - pp->io_bus_addr;
- pci_ioremap_io(global_io_offset, pp->io_base);
- global_io_offset += SZ_64K;
- pci_add_resource_offset(&sys->resources, &pp->io,
- sys->io_offset);
- }
-
- sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
- pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
- pci_add_resource(&sys->resources, &pp->busn);
-
- return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) -{
- struct pci_bus *bus;
- struct pcie_port *pp = sys_to_pcie(sys);
-
- pp->root_bus_nr = sys->busnr;
- bus = pci_create_root_bus(pp->dev, sys->busnr,
- &dw_pcie_ops, sys, &sys->resources);
- if (!bus)
- return NULL;
-
- pci_scan_child_bus(bus);
-
- if (bus && pp->ops->scan_bus)
- pp->ops->scan_bus(pp);
-
- return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{
- struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
- int irq;
-
- irq = of_irq_parse_and_map_pci(dev, slot, pin);
- if (!irq)
- irq = pp->irq;
-
- return irq;
-}
-
-static struct hw_pci dw_pci = {
- .setup = dw_pcie_setup,
- .scan = dw_pcie_scan_bus,
- .map_irq = dw_pcie_map_irq,
-};
-
void dw_pcie_setup_rc(struct pcie_port *pp) {
u32 val;
drivers/pci/host/pcie-designware.h +5 -5
@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;
@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;
drivers/pci/host/pcie-spear13xx.c +1 -1
@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp);
------------------------------------
------------------------------------
Quoted 238 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux-
pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
(quoted diff) +2
-1-int dw_pcie_host_init(struct pcie_port *pp) +int __init dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev); struct of_pci_range range; struct of_pci_range_parser parser; + struct pci_bus *bus;Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 499
Quoted 8 lines
(quoted diff) +1
-0struct resource *cfg_res; + LIST_HEAD(res); u32 val, na, ns; const __be32 *addrp; int i, index, ret;@@ -502,15 +498,49 @@ 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);
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +10
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io,Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 514
Quoted 5 lines
(quoted diff) +5
-0+ global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the
below arm64 code.
Quoted 8 lines
Quoted 4 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use a PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O
Bar.
There are two problems here:
1) the
io_baseaddress you get fromof_pci_get_host_bridge_resourcesmust be mapped usingpci_remap_iospace. You are not doing this, so even if you had a PCIe card with I/O bar it would not work on arm64 as the code stands. Remember that I/O space on arm/arm64 works as a memory access with offset fromPCI_IOBASEand that's the value you
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and arm64 so, as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 18 lines
Quoted 11 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 4 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warning on arm with the above change. Changing the the type indrivers/pci/host/pcie-designware.hfixes this.Quoted 4 lines
Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 528
Quoted 6 lines
(quoted diff) +6
-0+ pp, &res); + if (!bus) + return -ENOMEM; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip; #endif - dw_pci.nr_controllers = 1; - dw_pci.private_data = (void **)&pp; + pci_scan_child_bus(bus); + if (pp->ops->scan_bus) + pp->ops->scan_bus(pp);Quoted 4 lines
Quoted 4 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 539
Quoted 4 lines
(quoted diff) +3
-1- pci_common_init_dev(pp->dev, &dw_pci); +#ifdef CONFIG_ARM + /* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
Review static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
(quoted diff) +4
-0+#endif + + pci_assign_unassigned_bus_resources(bus); + pci_bus_add_devices(bus); return 0; }@@ -653,7 +683,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,
Quoted 7 lines
Quoted 7 lines
Review static int dw_pcie_valid_config(struct · line 689
Quoted 7 lines
(quoted diff) +1
-1int 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){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus, u32 devfn,
Quoted 82 lines
Quoted 11 lines
Quoted 11 lines
(quoted diff) +1
-2int where, int size, u32 val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
(quoted diff) +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ - struct pcie_port *pp; - - pp = sys_to_pcie(sys); -Review
Quoted 10 lines
(quoted diff) +0
-10- 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);Quoted 39 lines
Quoted 39 lines
(quoted diff) +0
-6- pci_add_resource(&sys->resources, &pp->busn); - - return 1; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{(quoted diff) +0
-18- struct pci_bus *bus; - struct pcie_port *pp = sys_to_pcie(sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); - if (!bus) - return NULL; - - pci_scan_child_bus(bus); - - if (bus && pp->ops->scan_bus) - pp->ops->scan_bus(pp); - - return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
(quoted diff) +0
-13- 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,Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +0
-3- .map_irq = dw_pcie_map_irq, -}; - void dw_pcie_setup_rc(struct pcie_port *pp) { u32 val;.
--
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
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 21 lines · Gabriele Paoloni
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve the resources associated to each pci host bridge window. The resources now are not copied to the designwarepcie_portpp, instead they are passed by pointer.This patch is intended to replace entirely "[PATCH v2 2/4]"; so I have also included all the changes about the other drivers
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.
Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors about this patch. And I think this patch is a experimental one, it could not be compiled successfully.
Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
(quoted diff) +1
-1-int dw_pcie_host_init(struct pcie_port *pp) +int __init dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev);
Review
Quoted 10 lines
(quoted diff) +4
-2- struct of_pci_range range; - struct of_pci_range_parser parser; + struct pci_bus *bus; struct resource *cfg_res; + LIST_HEAD(res); u32 val, na, ns; const __be32 *addrp; int i, index, ret; + int rlen; + struct pci_host_bridge_window *win;
This struct is not in latest kernel, I think you should use struct resource_entry.
Thanks,
Zhou
Quoted 554 lines
(quoted diff) +53
-58+ const __be32 *parser_range_end = of_get_property(np, "ranges", &rlen); + + if (parser_range_end == NULL) + return -ENOENT; + parser_range_end += rlen/sizeof(__be32); + /* Find the address cell size and the number of cells in order to get * the untranslated address.@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp) dev_err(pp->dev, "missing *config* reg space\n"); } - if (of_pci_range_parser_init(&parser, np)) { - dev_err(pp->dev, "missing ranges property\n"); - return -EINVAL; - } + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base); + if (ret) + return ret; /* Get the I/O and memory ranges from DT */ - for_each_of_pci_range(&parser, &range) { - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; - - if (restype == IORESOURCE_IO) { - of_pci_range_to_resource(&range, np, &pp->io); - pp->io.name = "I/O"; - pp->io.start = max_t(resource_size_t, - PCIBIOS_MIN_IO, - range.pci_addr + global_io_offset); - pp->io.end = min_t(resource_size_t, - IO_SPACE_LIMIT, - range.pci_addr + range.size - + global_io_offset - 1); - pp->io_size = resource_size(&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - - /* Find the untranslated IO space address */ - pp->io_mod_base = of_read_number(parser.range - - parser.np + na, ns); - } - if (restype == IORESOURCE_MEM) { - of_pci_range_to_resource(&range, np, &pp->mem); - pp->mem.name = "MEM"; - pp->mem_size = resource_size(&pp->mem); - pp->mem_bus_addr = range.pci_addr; - - /* Find the untranslated MEM space address */ - pp->mem_mod_base = of_read_number(parser.range - - parser.np + na, ns); - } - if (restype == 0) { - of_pci_range_to_resource(&range, np, &pp->cfg); - pp->cfg0_size = resource_size(&pp->cfg)/2; - pp->cfg1_size = resource_size(&pp->cfg)/2; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; + list_for_each_entry(win, &res, list) { + switch (resource_type(win->res)) { + case IORESOURCE_IO: + pp->io = win->res; + pp->io->name = "I/O"; + pp->io_size = resource_size(pp->io); + pp->io_bus_addr = pp->io->start - win->offset; + /* magic 5 below comes from magic na and ns in + * of_pci_range_parser_init() */ + pp->io_mod_base = of_read_number(parser_range_end - + of_n_addr_cells(np) - 5 + na, ns); + ret = pci_remap_iospace(pp->io, pp->io_base); + if (ret) { + dev_warn(pp->dev, "error %d: failed to map resource %pR\n", + ret, pp->io); + continue; + } + break; + case IORESOURCE_MEM: + pp->mem = win->res; + pp->mem->name = "MEM"; + pp->mem_size = resource_size(pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end - + of_n_addr_cells(np) - 5 + na, ns); + break; + case 0: + pp->cfg = win->res; + pp->cfg0_size = resource_size(pp->cfg)/2; + pp->cfg1_size = resource_size(pp->cfg)/2; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; /* Find the untranslated configuration space address */ - pp->cfg0_mod_base = of_read_number(parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base = of_read_number(parser_range_end - + of_n_addr_cells(np) - 5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; + break; + case IORESOURCE_BUS: + pp->busn = win->res; + break; + default: + continue; } } - ret = of_pci_parse_bus_range(np, &pp->busn); - if (ret < 0) { - pp->busn.name = np->name; - pp->busn.start = 0; - pp->busn.end = 0xff; - pp->busn.flags = IORESOURCE_BUS; - dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", - ret, &pp->busn); - } - if (!pp->dbi_base) { - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, - resource_size(&pp->cfg)); + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, + resource_size(pp->cfg)); if (!pp->dbi_base) { dev_err(pp->dev, "error with ioremap\n"); return -ENOMEM; } } - pp->mem_base = pp->mem.start; + pp->mem_base = pp->mem->start; if (!pp->va_cfg0_base) { pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, @@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)(quoted diff) +33
-11if (pp->ops->host_init) pp->ops->host_init(pp); - dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); + if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0) + != PCIBIOS_SUCCESSFUL) + return -EINVAL; /* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); + if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI) + != PCIBIOS_SUCCESSFUL) + return -EINVAL; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val) + != PCIBIOS_SUCCESSFUL) + return -EINVAL; - dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val); val |= PORT_LOGIC_SPEED_CHANGE; - dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; + if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val) + != PCIBIOS_SUCCESSFUL) + return -EINVAL; + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); + if (!bus) + return -ENOMEM; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain); #else + bus->msi = &dw_pcie_msi_chip; #endif - dw_pci.nr_controllers = 1; - dw_pci.private_data = (void **)&pp; + pci_scan_child_bus(bus); + if (pp->ops->scan_bus) + pp->ops->scan_bus(pp); - pci_common_init_dev(pp->dev, &dw_pci); +#ifdef CONFIG_ARM + /* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); #endif + + pci_assign_unassigned_bus_resources(bus); + pci_bus_add_devices(bus); return 0; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp, static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val){
(quoted diff) +1
-56- struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ - struct pcie_port *pp; - - pp = sys_to_pcie(sys); - - if (global_io_offset < SZ_1M && pp->io_size > 0) { - sys->io_offset = global_io_offset - pp->io_bus_addr; - pci_ioremap_io(global_io_offset, pp->io_base); - global_io_offset += SZ_64K; - pci_add_resource_offset(&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; - pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); - pci_add_resource(&sys->resources, &pp->busn); - - return 1; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) -{ - struct pci_bus *bus; - struct pcie_port *pp = sys_to_pcie(sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); - if (!bus) - return NULL; - - pci_scan_child_bus(bus); - - if (bus && pp->ops->scan_bus) - pp->ops->scan_bus(pp); - - return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); - int irq; - - irq = of_irq_parse_and_map_pci(dev, slot, pin); - if (!irq) - irq = pp->irq; - - return irq; -} - -static struct hw_pci dw_pci = { - .setup = dw_pcie_setup, - .scan = dw_pcie_scan_bus, - .map_irq = dw_pcie_map_irq, -}; - void dw_pcie_setup_rc(struct pcie_port *pp) { u32 val;drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;drivers/pci/host/pcie-spear13xx.c +1
-3@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 155 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux-
pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
(quoted diff) +2
-1-int dw_pcie_host_init(struct pcie_port *pp) +int __init dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev); struct of_pci_range range; struct of_pci_range_parser parser; + struct pci_bus *bus;Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 499
Quoted 8 lines
(quoted diff) +1
-0struct resource *cfg_res; + LIST_HEAD(res); u32 val, na, ns; const __be32 *addrp; int i, index, ret;@@ -502,15 +498,49 @@ 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);
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +10
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io,Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 514
Quoted 5 lines
(quoted diff) +5
-0+ global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the
below arm64 code.
Quoted 8 lines
Quoted 4 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use a PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O
Bar.
There are two problems here:
1) the
io_baseaddress you get fromof_pci_get_host_bridge_resourcesmust be mapped usingpci_remap_iospace. You are not doing this, so even if you had a PCIe card with I/O bar it would not work on arm64 as the code stands. Remember that I/O space on arm/arm64 works as a memory access with offset fromPCI_IOBASEand that's the value you
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and arm64 so, as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 18 lines
Quoted 11 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 4 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warning on arm with the above change. Changing the the type indrivers/pci/host/pcie-designware.hfixes this.Quoted 4 lines
Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 528
Quoted 6 lines
(quoted diff) +6
-0+ pp, &res); + if (!bus) + return -ENOMEM; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip; #endif - dw_pci.nr_controllers = 1; - dw_pci.private_data = (void **)&pp; + pci_scan_child_bus(bus); + if (pp->ops->scan_bus) + pp->ops->scan_bus(pp);Quoted 4 lines
Quoted 4 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 539
Quoted 4 lines
(quoted diff) +3
-1- pci_common_init_dev(pp->dev, &dw_pci); +#ifdef CONFIG_ARM + /* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
Review static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
(quoted diff) +4
-0+#endif + + pci_assign_unassigned_bus_resources(bus); + pci_bus_add_devices(bus); return 0; }@@ -653,7 +683,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,
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
(quoted diff) +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret;Quoted 87 lines
Quoted 1 line
Quoted 1 line
Review static int dw_pcie_valid_config(struct · line 689
Quoted 1 line
(quoted diff) +0
-0if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus, u32 devfn,
Quoted 82 lines
Quoted 11 lines
Quoted 11 lines
(quoted diff) +1
-2int where, int size, u32 val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
(quoted diff) +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ - struct pcie_port *pp; - - pp = sys_to_pcie(sys); -Review
Quoted 10 lines
(quoted diff) +0
-10- 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);Quoted 39 lines
Quoted 39 lines
(quoted diff) +0
-6- pci_add_resource(&sys->resources, &pp->busn); - - return 1; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{(quoted diff) +0
-18- struct pci_bus *bus; - struct pcie_port *pp = sys_to_pcie(sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); - if (!bus) - return NULL; - - pci_scan_child_bus(bus); - - if (bus && pp->ops->scan_bus) - pp->ops->scan_bus(pp); - - return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
(quoted diff) +0
-13- 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,Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +0
-3- .map_irq = dw_pcie_map_irq, -}; - void dw_pcie_setup_rc(struct pcie_port *pp) { u32 val;.
--
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.
PATCH v2 2/4 PCI: designware: Add ARM64 support
Hi Zhou Wang
I apologize, I made a mistake as I didn't rebase the patch on the latest Kernel (where I was convinced I did), my bad.
The patch below is based on v4.1-rc7
It passes checkpatch and compiles OK
Cheers
Gab
-------------------------------------------
-------------------------------------------
This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.
The intention is to complete the unification between ARM and ARM64 now that the dependency on arch/arm/kernel/bios32.c is gone.
I have also included the rework asked by James Morse:io_base declared as resource_size_t
It compiles fine on ARCH arm and arm64 on Linux 4.1-rc7.
It needs to be tested.
--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 242 +++++++++++++++---------------------- drivers/pci/host/pcie-designware.h | 10 +- drivers/pci/host/pcie-spear13xx.c | 2 +- 8 files changed, 109 insertions(+), 154 deletions(-)
drivers/pci/host/pci-dra7xx.c +1 -0
@@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, pp = &dra7xx->pp; pp->dev = dev; + pp->root_bus_nr =0 ; pp->ops = &dra7xx_pcie_host_ops; pp->irq =platform_get_irq (pdev,1 );
drivers/pci/host/pci-exynos.c +1 -1
@@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &exynos_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pci-imx6.c +1 -1
@@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &imx6_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pci-keystone.c +1 -1
@@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &keystone_pcie_host_ops; ret =ks_dw_pcie_host_init (ks_pcie, ks_pcie->msi_intc_np);if (ret) {
drivers/pci/host/pci-layerscape.c +1 -1
@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);
drivers/pci/host/pcie-designware.c +98 -144
337 lines not on this page · raw message
drivers/pci/host/pcie-designware.h +5 -5
@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;
@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;
drivers/pci/host/pcie-spear13xx.c +1 -1
@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp);
--------------------------------------------------
--------------------------------------------------
Quoted 671 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 3 lines · Gabriele Paoloni
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve the resources associated to each pci host bridge window.Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I
have also included all the changes about the other drivers
Quoted 15 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors
about this patch. And I think this patch is a experimental one, it could not
be compiled successfully.Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
(quoted diff) +1
-1-int dw_pcie_host_init(struct pcie_port *pp) +int __init dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev);Review
Quoted 10 lines
(quoted diff) +4
-2- struct of_pci_range range; - struct of_pci_range_parser parser; + struct pci_bus *bus; struct resource *cfg_res; + LIST_HEAD(res); u32 val, na, ns; const __be32 *addrp; int i, index, ret; + int rlen; + struct pci_host_bridge_window *win;This struct is not in latest kernel, I think you should use struct
resource_entry.Thanks,
ZhouReview
Quoted 1 line
(quoted diff) +1
-0+ const __be32 *parser_range_end = of_get_property(np, "ranges",&rlen);
Review
Quoted 7 lines
(quoted diff) +5
-0+ + if (parser_range_end == NULL) + return -ENOENT; + parser_range_end += rlen/sizeof(__be32); + /* Find the address cell size and the number of cells in order toget
Quoted 56 lines
(quoted diff) +7
-41* the untranslated address.@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp) dev_err(pp->dev, "missing *config* reg space\n"); } - if (of_pci_range_parser_init(&parser, np)) { - dev_err(pp->dev, "missing ranges property\n"); - return -EINVAL; - } + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp- io_base); + if (ret) + return ret; /* Get the I/O and memory ranges from DT */ - for_each_of_pci_range(&parser, &range) { - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; - - if (restype == IORESOURCE_IO) { - of_pci_range_to_resource(&range, np, &pp->io); - pp->io.name = "I/O"; - pp->io.start = max_t(resource_size_t, - PCIBIOS_MIN_IO, - range.pci_addr + global_io_offset); - pp->io.end = min_t(resource_size_t, - IO_SPACE_LIMIT, - range.pci_addr + range.size - + global_io_offset - 1); - pp->io_size = resource_size(&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - - /* Find the untranslated IO space address */ - pp->io_mod_base = of_read_number(parser.range - - parser.np + na, ns); - } - if (restype == IORESOURCE_MEM) { - of_pci_range_to_resource(&range, np, &pp->mem); - pp->mem.name = "MEM"; - pp->mem_size = resource_size(&pp->mem); - pp->mem_bus_addr = range.pci_addr; - - /* Find the untranslated MEM space address */ - pp->mem_mod_base = of_read_number(parser.range - - parser.np + na, ns); - } - if (restype == 0) { - of_pci_range_to_resource(&range, np, &pp->cfg); - pp->cfg0_size = resource_size(&pp->cfg)/2; - pp->cfg1_size = resource_size(&pp->cfg)/2; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; + list_for_each_entry(win, &res, list) { + switch (resource_type(win->res)) { + case IORESOURCE_IO: + pp->io = win->res;Review int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
(quoted diff) +10
-0+ pp->io->name = "I/O"; + pp->io_size = resource_size(pp->io); + pp->io_bus_addr = pp->io->start - win->offset; + /* magic 5 below comes from magic na and ns in + * of_pci_range_parser_init() */ + pp->io_mod_base = of_read_number(parser_range_end - + of_n_addr_cells(np) - 5 + na, ns); + ret = pci_remap_iospace(pp->io, pp->io_base); + if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
(quoted diff) +10
-0+ ret, pp->io); + continue; + } + break; + case IORESOURCE_MEM: + pp->mem = win->res; + pp->mem->name = "MEM"; + pp->mem_size = resource_size(pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -Review int dw_pcie_host_init(struct pcie_port *pp) · line 417
Quoted 10 lines
(quoted diff) +8
-0+ of_n_addr_cells(np) - 5 + na, ns); + break; + case 0: + pp->cfg = win->res; + pp->cfg0_size = resource_size(pp->cfg)/2; + pp->cfg1_size = resource_size(pp->cfg)/2; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; /* Find the untranslated configuration space address*/
Quoted 13 lines
(quoted diff) +9
-4- pp->cfg0_mod_base = of_read_number(parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base = of_read_number(parser_range_end - + of_n_addr_cells(np) - 5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; + break; + case IORESOURCE_BUS: + pp->busn = win->res; + break; + default: + continue;Review int dw_pcie_host_init(struct pcie_port *pp) · line 437
Quoted 10 lines
(quoted diff) +0
-7} } - 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",
Quoted 18 lines
(quoted diff) +3
-6- 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) {Quoted 1 line
pp->va_cfg0_base= devm_ioremap(pp->dev,pp->cfg0_base, @@-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)Review
Quoted 10 lines
(quoted diff) +3
-2if (pp->ops->host_init) pp->ops->host_init(pp); - dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); + if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0) + != PCIBIOS_SUCCESSFUL) + return -EINVAL; /* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Review
Quoted 1 line
(quoted diff) +1
-0+ if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)Review
Quoted 4 lines
(quoted diff) +4
-0+ != PCIBIOS_SUCCESSFUL) + return -EINVAL; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 25 lines
(quoted diff) +15
-5+ != PCIBIOS_SUCCESSFUL) + return -EINVAL; - dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val); val |= PORT_LOGIC_SPEED_CHANGE; - dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; + if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val) + != PCIBIOS_SUCCESSFUL) + return -EINVAL; + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); + if (!bus) + return -ENOMEM; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain); #else + bus->msi = &dw_pcie_msi_chip; #endifReview
Quoted 10 lines
(quoted diff) +6
-3- dw_pci.nr_controllers = 1; - dw_pci.private_data = (void **)&pp; + pci_scan_child_bus(bus); + if (pp->ops->scan_bus) + pp->ops->scan_bus(pp); - pci_common_init_dev(pp->dev, &dw_pci); +#ifdef CONFIG_ARM + /* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Review static int dw_pcie_valid_config(struct pcie_port
Quoted 7 lines
(quoted diff) +3
-0+ + pci_assign_unassigned_bus_resources(bus); + pci_bus_add_devices(bus); return 0; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where,Review static int dw_pcie_valid_config(struct pcie_port · line 670
Quoted 7 lines
(quoted diff) +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus, u32 devfn,Review
Quoted 7 lines
(quoted diff) +0
-0int where, int size, u32 val){
(quoted diff) +1
-1- struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 19 lines
(quoted diff) +0
-15.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);Review
Quoted 6 lines
(quoted diff) +0
-6- pci_add_resource(&sys->resources, &pp->busn); - - return 1; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data*sys) -{
Quoted 8 lines
(quoted diff) +0
-8- struct pci_bus *bus; - struct pcie_port *pp = sys_to_pcie(sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); - if (!bus) - return NULL;Review
Quoted 10 lines
(quoted diff) +0
-10- - pci_scan_child_bus(bus); - - if (bus && pp->ops->scan_bus) - pp->ops->scan_bus(pp); - - return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
Review
Quoted 19 lines
(quoted diff) +0
-16- 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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 68 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 58 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux-
pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
(quoted diff) +2
-1-int dw_pcie_host_init(struct pcie_port *pp) +int __init dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev); struct of_pci_range range; struct of_pci_range_parser parser; + struct pci_bus *bus;Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 499
Quoted 8 lines
(quoted diff) +1
-0struct resource *cfg_res; + LIST_HEAD(res); u32 val, na, ns; const __be32 *addrp; int i, index, ret;@@ -502,15 +498,49 @@ 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);
Quoted 22 lines
Quoted 22 lines
Quoted 9 lines
(quoted diff) +5
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testingReview int dw_pcie_host_init(struct pcie_port *pp) · line 514
Quoted 10 lines
(quoted diff) +10
-0+ */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the
Quoted 7 lines
Quoted 7 lines
below arm64 code.
Quoted 6 lines
Quoted 4 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use
a
Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O
Bar.
There are two problems here:
1) the
io_baseaddress you get fromof_pci_get_host_bridge_resourcesmust be mapped usingpci_remap_iospace. You are not doing this,so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work on
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64 works as
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's the valueyou
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and arm64
so,
Quoted 8 lines
Quoted 8 lines
as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 3 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warningon
Quoted 106 lines
Quoted 106 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 528
Quoted 6 lines
(quoted diff) +6
-0+ pp, &res); + if (!bus) + return -ENOMEM; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip; #endif - dw_pci.nr_controllers = 1; - dw_pci.private_data = (void **)&pp; + pci_scan_child_bus(bus); + if (pp->ops->scan_bus) + pp->ops->scan_bus(pp);Quoted 4 lines
Quoted 4 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 539
Quoted 4 lines
(quoted diff) +3
-1- pci_common_init_dev(pp->dev, &dw_pci); +#ifdef CONFIG_ARM + /* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
Review static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
(quoted diff) +4
-0+#endif + + pci_assign_unassigned_bus_resources(bus); + pci_bus_add_devices(bus); return 0; }@@ -653,7 +683,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,
Quoted 7 lines
Quoted 7 lines
Review static int dw_pcie_valid_config(struct · line 689
Quoted 7 lines
(quoted diff) +1
-1int 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){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus, u32 devfn,
Quoted 44 lines
Quoted 11 lines
Quoted 11 lines
(quoted diff) +1
-2int where, int size, u32 val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
(quoted diff) +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ - struct pcie_port *pp; - - pp = sys_to_pcie(sys); -Review
Quoted 10 lines
(quoted diff) +0
-10- 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);Quoted 17 lines
Quoted 17 lines
(quoted diff) +0
-6- pci_add_resource(&sys->resources, &pp->busn); - - return 1; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{(quoted diff) +0
-10- struct pci_bus *bus; - struct pcie_port *pp = sys_to_pcie(sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); - if (!bus) - return NULL; - - pci_scan_child_bus(bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Review
Quoted 8 lines
(quoted diff) +0
-8- - 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
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 23 lines
Quoted 9 lines
pin) -{
(quoted diff) +0
-8- 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;Review
Quoted 10 lines
(quoted diff) +0
-8-} - -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;.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to majordomo at vger.kernel.org More
majordomo
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
.
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 4 lines · Gabriele Paoloni
Hi Zhou Wang
I apologize, I made a mistake as I didn't rebase the patch on the latest Kernel (where I was convinced I did), my bad.
Quoted 8 lines
The patch below is based on v4.1-rc7
It passes checkpatch and compiles OK
Cheers
Gab
Hi Gab,
I will try to merge your patch into next version, please help to review :)
Many thanks for your patch.
Zhou
Quoted 1,164 lines
-------------------------------------------
-------------------------------------------
This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64 on Linux 4.1-rc7.
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 242 +++++++++++++++---------------------- drivers/pci/host/pcie-designware.h | 10 +- drivers/pci/host/pcie-spear13xx.c | 2 +- 8 files changed, 109 insertions(+), 154 deletions(-)drivers/pci/host/pci-dra7xx.c +1
-0@@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, pp = &dra7xx->pp; pp->dev = dev; + pp->root_bus_nr =0 ; pp->ops = &dra7xx_pcie_host_ops; pp->irq =platform_get_irq (pdev,1 );drivers/pci/host/pci-exynos.c +1
-1@@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &exynos_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pci-imx6.c +1
-1@@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &imx6_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pci-keystone.c +1
-1@@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &keystone_pcie_host_ops; ret =ks_dw_pcie_host_init (ks_pcie, ks_pcie->msi_intc_np);if (ret) {drivers/pci/host/pci-layerscape.c +1
-1@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pcie-designware.c +98
-144@@ -11,6 +11,7 @@* published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -67,16 +68,7 @@#define PCIE_ATU_FUNC (x) (((x) & 0x7) << 16)#define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; - -static unsigned long global_io_offset; - -static inline struct pcie_port *sys_to_pcie (struct pci_sys_data *sys) -{ -BUG_ON (!sys->private_data); - -return sys->private_data; -} +static struct pci_ops dw_pcie_ops;int dw_pcie_cfg_read (void __iomem *addr,int where,int size,u32 *val) {@@ -238,7 +230,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)static int assign_irq (int no_irqs,struct msi_desc *desc,int *pos) {int irq, pos0, i; -struct pcie_port *pp =sys_to_pcie (desc->dev->bus->sysdata); +struct pcie_port *pp = desc->dev->bus->sysdata; pos0 =bitmap_find_free_region (pp->msi_irq_in_use,MAX_MSI_IRQS ,order_base_2 (no_irqs));@@ -281,7 +273,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, {int irq, pos;struct msi_msg msg; -struct pcie_port *pp =sys_to_pcie (pdev->bus->sysdata); +struct pcie_port *pp = pdev->bus->sysdata;if (desc->msi_attrib.is_msix)return -EINVAL ;@@ -310,7 +302,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) {struct irq_data *data =irq_get_irq_data (irq);struct msi_desc *msi =irq_data_get_msi (data); -struct pcie_port *pp =sys_to_pcie (msi->dev->bus->sysdata); +struct pcie_port *pp = msi->dev->bus->sysdata;clear_irq_range (pp, irq,1 , data->hwirq); }@@ -342,16 +334,24 @@ static const struct irq_domain_ops msi_domain_ops = { .map = dw_pcie_msi_map, }; -int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev); -struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct resource_entry *win; +const __be32 *parser_range_end =of_get_property (np,"ranges" , &rlen); + +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get * the untranslated address. @@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +resource_list_for_each_entry (win, &res) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res; + pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { +dev_warn (pp->dev,"error %d: failed to map resource %pR\n" , + ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */ - pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ; } } - ret =of_pci_parse_bus_range (np, &pp->busn); -if (ret <0 ) { - pp->busn.name = np->name; - pp->busn.start =0 ; - pp->busn.end =0xff ; - pp->busn.flags =IORESOURCE_BUS ; -dev_dbg (pp->dev,"failed to parse bus-range property: %d, using default %pR\n" , - ret, &pp->busn); - } -if (!pp->dbi_base) { - pp->dbi_base =devm_ioremap (pp->dev, pp->cfg.start, -resource_size (&pp->cfg)); + pp->dbi_base =devm_ioremap (pp->dev, pp->cfg->start, +resource_size (pp->cfg));if (!pp->dbi_base) {dev_err (pp->dev,"error with ioremap\n" );return -ENOMEM ; } } - pp->mem_base = pp->mem.start; + pp->mem_base = pp->mem->start;if (!pp->va_cfg0_base) { pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,@@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)if (pp->ops->host_init) pp->ops->host_init (pp); -dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ); +if (dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ;/* program correct class for RC */ -dw_pcie_wr_own_conf (pp,PCI_CLASS_DEVICE ,2 ,PCI_CLASS_BRIDGE_PCI ); +if (dw_pcie_wr_own_conf (pp,PCI_CLASS_DEVICE ,2 ,PCI_CLASS_BRIDGE_PCI ) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + +if (dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +if (dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; -pci_add_resource_offset (&sys->resources, &pp->mem, sys->mem_offset); -pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus (int nr,struct pci_sys_data *sys) -{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pcie_port *pp =sys_to_pcie (dev->bus->sysdata); -int irq; - - irq =of_irq_parse_and_map_pci (dev, slot, pin); -if (!irq) - irq = pp->irq; - -return irq; -} - -static struct hw_pci dw_pci = { - .setup = dw_pcie_setup, - .scan = dw_pcie_scan_bus, - .map_irq = dw_pcie_map_irq, -}; -void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;drivers/pci/host/pcie-spear13xx.c +1
-3@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); -------------------------------------------------- --------------------------------------------------Quoted 661 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 3 lines · Gabriele Paoloni
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve the resources associated to each pci host bridge window.Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I
have also included all the changes about the other drivers
Quoted 15 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors
about this patch. And I think this patch is a experimental one, it could not
be compiled successfully.Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +4
-2-struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct pci_host_bridge_window *win;This struct is not in latest kernel, I think you should use struct
resource_entry.Thanks,
ZhouReview
Quoted 1 line
(quoted diff) +1
-0+ const __be32 *parser_range_end = of_get_property(np, "ranges",&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get
Quoted 56 lines
drivers/pci/host/pcie-designware.c +7
-41* the untranslated address. @@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp- io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +list_for_each_entry (win, &res, list) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-0+ of_n_addr_cells(np) - 5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */
Quoted 13 lines
drivers/pci/host/pcie-designware.c +9
-4- pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7} } - 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",
Quoted 18 lines
drivers/pci/host/pcie-designware.c +3
-6- 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) {Quoted 1 line
pp->va_cfg0_base= devm_ioremap(pp->dev,pp->cfg0_base, @@-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +3
-2if (pp->ops->host_init) pp->ops->host_init (pp); -dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ); +if (dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Review
Quoted 1 line
(quoted diff) +1
-0+ if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 25 lines
drivers/pci/host/pcie-designware.c +15
-5+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +if (dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain);#else + bus->msi = &dw_pcie_msi_chip;#endif drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 521
Quoted 10 lines
drivers/pci/host/pcie-designware.c +6
-3- dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port
Quoted 7 lines
drivers/pci/host/pcie-designware.c +3
-0+ +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where,drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus, u32 devfn,drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-0int where, int size, u32 val){
drivers/pci/host/pcie-designware.c +1
-1-struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 19 lines
drivers/pci/host/pcie-designware.c +0
-15.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);drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 6 lines
drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data*sys) -{
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
Review
Quoted 19 lines
drivers/pci/host/pcie-designware.c +0
-16-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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 68 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 58 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux-
pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c +2
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;struct of_pci_range_parser parser; +struct pci_bus *bus;Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 499
Quoted 8 lines
drivers/pci/host/pcie-designware.c +1
-0struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ 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);
Quoted 22 lines
Quoted 22 lines
Quoted 9 lines
(quoted diff) +5
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testingReview int dw_pcie_host_init(struct pcie_port *pp) · line 514
Quoted 10 lines
(quoted diff) +10
-0+ */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the
Quoted 7 lines
Quoted 7 lines
below arm64 code.
Quoted 6 lines
Quoted 4 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use
a
Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O
Bar.
There are two problems here:
1) the
io_baseaddress you get fromof_pci_get_host_bridge_resourcesmust be mapped usingpci_remap_iospace. You are not doing this,so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work on
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64 works as
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's the valueyou
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and arm64
so,
Quoted 8 lines
Quoted 8 lines
as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 3 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warningon
Quoted 106 lines
Quoted 106 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port *pp) · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp);Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +3
-1-pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
drivers/pci/host/pcie-designware.c +4
-0+#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,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,
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int 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 ){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus, u32 devfn,
Quoted 44 lines
Quoted 11 lines
Quoted 11 lines
drivers/pci/host/pcie-designware.c +1
-2int where, int size, u32 val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); -drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10-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);Quoted 17 lines
Quoted 17 lines
drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{drivers/pci/host/pcie-designware.c +0
-10-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 23 lines
Quoted 9 lines
pin) -{
drivers/pci/host/pcie-designware.c +0
-8-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;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 718
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-8-} - -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;.
Quoted 11 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to majordomo at vger.kernel.org More
majordomo
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
.
.
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 24 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Tuesday, June 16, 2015 12:30 PM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 3 lines · Gabriele Paoloni
Hi Zhou Wang
I apologize, I made a mistake as I didn't rebase the patch on the
latest Kernel (where I was convinced I did), my bad.
Quoted 7 lines
The patch below is based on v4.1-rc7
It passes checkpatch and compiles OK
Cheers
Quoted 8 lines
Quoted 2 lines
Gab
Hi Gab,
I will try to merge your patch into next version, please help to review :)
Sure I will :)
Thanks
Gab
Quoted 1,218 lines
Many thanks for your patch.
ZhouQuoted 17 lines
-------------------------------------------
-------------------------------------------
This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64 on Linux 4.1-rc7.
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>Quoted 7 lines
--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 242 +++++++++++++++----------------------
drivers/pci/host/pci-
Quoted 5 lines
drivers/pci/host/pcie-designware.h | 10 +- drivers/pci/host/pcie-spear13xx.c | 2 +- 8 files changed, 109 insertions(+), 154 deletions(-)drivers/pci/host/pci- renamed from drivers/pci/host/pci-dra7xx.c +0
-0
dra7xx.cdrivers/pci/host/pci-dra7xx.c static int __init dra7xx_add_pcie_port(struct
Quoted 4 lines
index 2d57e19..5c8b6ab 100644
drivers/pci/host/pci-dra7xx.c +0
-0@@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct
dra7xx_pcie*dra7xx,drivers/pci/host/pci-
Quoted 8 lines
drivers/pci/host/pci-dra7xx.c +1
-0pp = &dra7xx->pp; pp->dev = dev; + pp->root_bus_nr =0 ; pp->ops = &dra7xx_pcie_host_ops; pp->irq =platform_get_irq (pdev,1 );drivers/pci/host/pci- renamed from drivers/pci/host/pci-exynos.c +0
-0
exynos.cdrivers/pci/host/pci-exynos.c static int __init exynos_add_pcie_port(struct
Quoted 4 lines
index c139237..4b6db6c 100644
drivers/pci/host/pci-exynos.c +0
-0@@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct
pcie_port*pp,drivers/pci/host/pci-
Quoted 9 lines
drivers/pci/host/pci-exynos.c +1
-1} } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &exynos_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pci- renamed from drivers/pci/host/pci-imx6.c +0
-0
imx6.cdrivers/pci/host/pci-imx6.c static int __init imx6_add_pcie_port(struct
Quoted 4 lines
index fdb9536..c4a80c5 100644
drivers/pci/host/pci-imx6.c +0
-0@@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct
pcie_port*pp,drivers/pci/host/pci-
Quoted 9 lines
drivers/pci/host/pci-imx6.c +1
-1} } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &imx6_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pci- renamed from drivers/pci/host/pci-keystone.c +0
-0
keystone.cdrivers/pci/host/pci-keystone.c static int __init ks_add_pcie_port(struct
Quoted 4 lines
index 75333b0..df91f5e 100644
drivers/pci/host/pci-keystone.c +0
-0@@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct
keystone_pcie*ks_pcie,Review
Quoted 9 lines
drivers/pci/host/pci-keystone.c +1
-1return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &keystone_pcie_host_ops; ret =ks_dw_pcie_host_init (ks_pcie, ks_pcie->msi_intc_np);if (ret) {(quoted diff) +0
-0
b/drivers/pci/host/pci-layerscape.cReview
Quoted 13 lines
index 4a6e62f..5c7a9c4 100644
drivers/pci/host/pci-layerscape.c +1
-1@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.cQuoted 18 lines
index 2e9f84f..844febee 100644
drivers/pci/host/pcie-designware.c +1
-3@@ -11,6 +11,7 @@* published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -67,16 +68,7 @@#define PCIE_ATU_FUNC (x) (((x) & 0x7) << 16)#define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; - -static unsigned long global_io_offset;drivers/pci/host/pcie-designware.c line 73
Quoted 10 lines
drivers/pci/host/pcie-designware.c +1
-7- -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)
drivers/pci/host/pcie-designware.c static void dw_pcie_msi_set_irq(struct pcie_port
Quoted 2 lines
drivers/pci/host/pcie-designware.c +0
-0{@@ -238,7 +230,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port*pp, int irq)
drivers/pci/host/pcie-designware.c static int dw_msi_setup_irq(struct msi_controller
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1static int assign_irq (int no_irqs,struct msi_desc *desc,int *pos) {int irq, pos0, i; -struct pcie_port *pp =sys_to_pcie (desc->dev->bus->sysdata); +struct pcie_port *pp = desc->dev->bus->sysdata; pos0 =bitmap_find_free_region (pp->msi_irq_in_use,MAX_MSI_IRQS ,order_base_2 (no_irqs));@@ -281,7 +273,7 @@ static int dw_msi_setup_irq(struct msi_controller*chip, struct
pci_dev*pdev,drivers/pci/host/pcie-designware.c static void dw_msi_teardown_irq(struct
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1{int irq, pos;struct msi_msg msg; -struct pcie_port *pp =sys_to_pcie (pdev->bus->sysdata); +struct pcie_port *pp = pdev->bus->sysdata;if (desc->msi_attrib.is_msix)return -EINVAL ;@@ -310,7 +302,7 @@ static void dw_msi_teardown_irq(struct
msi_controller*chip, unsigned int irq)drivers/pci/host/pcie-designware.c static const struct irq_domain_ops
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1{struct irq_data *data =irq_get_irq_data (irq);struct msi_desc *msi =irq_data_get_msi (data); -struct pcie_port *pp =sys_to_pcie (msi->dev->bus->sysdata); +struct pcie_port *pp = msi->dev->bus->sysdata;clear_irq_range (pp, irq,1 , data->hwirq); }@@ -342,16 +334,24 @@ static const struct irq_domain_ops
msi_domain_ops= {Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-2.map = dw_pcie_msi_map, }; -int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev); -struct of_pci_range range;drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-1-struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct resource_entry *win; + const __be32 *parser_range_end = of_get_property(np, "ranges",&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get
Quoted 56 lines
drivers/pci/host/pcie-designware.c +7
-41* the untranslated address. @@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp- io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +resource_list_for_each_entry (win, &res) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-0+ of_n_addr_cells(np) - 5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */
Quoted 13 lines
drivers/pci/host/pcie-designware.c +9
-4- pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7} } - 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",
Quoted 20 lines
drivers/pci/host/pcie-designware.c +3
-6- 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) {drivers/pci/host/pcie-designware.c +0
-0pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 499
Quoted 10 lines
drivers/pci/host/pcie-designware.c +3
-2@@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)if (pp->ops->host_init) pp->ops->host_init (pp); -dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ); +if (dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 490
Quoted 1 line
drivers/pci/host/pcie-designware.c +1
-0+ if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 11 lines
drivers/pci/host/pcie-designware.c +3
-5+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; + if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller,domain);
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port
Quoted 22 lines
drivers/pci/host/pcie-designware.c +12
-3+#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port*pp,
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus,
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,u32 devfn, int where,
Quoted 25 lines
drivers/pci/host/pcie-designware.c +1
-14static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - }drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 726
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-9- - 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)
Quoted 9 lines
drivers/pci/host/pcie-designware.c +0
-9-{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin)
Review
Quoted 21 lines
drivers/pci/host/pcie-designware.c +0
-17-{ -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) {drivers/pci/host/pcie-designware.c +0
-0u32 val;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 12 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); -------------------------------------------------- --------------------------------------------------Quoted 5 lines
Quoted 5 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han;Pratyush
Quoted 6 lines
Quoted 6 lines
Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 6 lines
Quoted 6 lines · Gabriele Paoloni
Quoted 3 lines
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve theresources
Quoted 262 lines
Quoted 262 lines
associated to each pci host bridge window.
Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I
have also included all the changes about the other drivers
Quoted 15 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors
about this patch. And I think this patch is a experimental one, it could not
be compiled successfully.Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +4
-2-struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct pci_host_bridge_window *win;This struct is not in latest kernel, I think you should use struct
resource_entry.Thanks,
ZhouReview
Quoted 1 line
(quoted diff) +1
-0+ const __be32 *parser_range_end = of_get_property(np, "ranges",&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get
Quoted 56 lines
drivers/pci/host/pcie-designware.c +7
-41* the untranslated address. @@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp- io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +list_for_each_entry (win, &res, list) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-0+ of_n_addr_cells(np) - 5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */
Quoted 13 lines
drivers/pci/host/pcie-designware.c +9
-4- pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7} } - 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",
Quoted 18 lines
drivers/pci/host/pcie-designware.c +3
-6- 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) {Quoted 1 line
pp->va_cfg0_base= devm_ioremap(pp->dev,pp->cfg0_base, @@-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +3
-2if (pp->ops->host_init) pp->ops->host_init (pp); -dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ); +if (dw_pcie_wr_own_conf (pp,PCI_BASE_ADDRESS_0 ,4 ,0 ) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Review
Quoted 1 line
(quoted diff) +1
-0+ if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 25 lines
drivers/pci/host/pcie-designware.c +15
-5+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +if (dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain);#else + bus->msi = &dw_pcie_msi_chip;#endif drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 521
Quoted 10 lines
drivers/pci/host/pcie-designware.c +6
-3- dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct
Quoted 7 lines
drivers/pci/host/pcie-designware.c +3
-0+ +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct
pcie_portQuoted 11 lines
Quoted 11 lines
*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where,drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus,u32
Quoted 26 lines
Quoted 26 lines
devfn,
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-0int where, int size, u32 val){
drivers/pci/host/pcie-designware.c +1
-1-struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 17 lines
drivers/pci/host/pcie-designware.c +0
-14.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;Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
(quoted diff) +0
-1- pci_add_resource_offset(&sys->resources, &pp->mem, sys-
mem_offset);drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_dataQuoted 88 lines
Quoted 88 lines
*sys) -{
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
Review
Quoted 19 lines
drivers/pci/host/pcie-designware.c +0
-16-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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 14 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang;Zhudacai;
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port
Quoted 8 lines
drivers/pci/host/pcie-designware.c +2
-0struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ int dw_pcie_host_init(struct pcie_port*pp)
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 2 lines
Quoted 2 lines
Review int dw_pcie_host_init(struct pcie_port · line 499
Quoted 2 lines
(quoted diff) +0
-0val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,val);
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +10
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port · line 514
Quoted 5 lines
(quoted diff) +5
-0+ global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just
the
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
below arm64 code.
Quoted 2 lines
Quoted 2 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went
as
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we
use
Quoted 2 lines
Quoted 2 lines
a
Quoted 1 line
Quoted 1 line
Quoted 1 line
PCIe device with a I/O Bar, it may not work well without above
code.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
But so far, I have not met a PCIe device which must work with a
I/O
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Bar.
There are two problems here:
1) the
io_baseaddress you get from
of_pci_get_host_bridge_resourcesQuoted 5 lines
Quoted 5 lines
Quoted 1 line
Quoted 1 line
must be mapped using
pci_remap_iospace. You are not doing this,so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work on
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64 works
as
Quoted 11 lines
Quoted 11 lines
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's the valueyou
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and
arm64
Quoted 73 lines
Quoted 73 lines
so,
Quoted 8 lines
Quoted 8 lines
as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port · line 517
Quoted 3 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warningon
Quoted 57 lines
Quoted 57 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp);Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +3
-1-pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
drivers/pci/host/pcie-designware.c +4
-0+#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,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,
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret;Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, · line 695
Quoted 1 line
drivers/pci/host/pcie-designware.c +0
-0if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct
pci_busQuoted 94 lines
Quoted 79 lines
Quoted 45 lines
Quoted 45 lines
*bus, u32 devfn,
Quoted 44 lines
Quoted 11 lines
Quoted 11 lines
drivers/pci/host/pcie-designware.c +1
-2int where, int size, u32 val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); -drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10-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);Quoted 17 lines
Quoted 17 lines
drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{drivers/pci/host/pcie-designware.c +0
-10-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 23 lines
Quoted 9 lines
pin) -{
drivers/pci/host/pcie-designware.c +0
-8-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;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 718
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-8-} - -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;.
Quoted 11 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to majordomo at vger.kernel.org More
majordomo
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
.
.
PATCH v2 2/4 PCI: designware: Add ARM64 support
On Tue, Jun 16, 2015 at 03:14:21PM +0100, Gabriele Paoloni wrote:
[...]
Quoted 2 lines
Quoted 2 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 505
Quoted 2 lines
drivers/pci/host/pcie-designware.c +2
-0+ bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res);
I think you can't do that on ARM 32-bit platforms. They rely on pci_sys_data in pcibios_msi_controller and pcibios_align_resource, if you do not pass a pci_sys_data struct in the sysdata pointer this can't work and unless you get lucky it will explode.
We have to remove pci_sys_data dependency on ARM, then this approach will work.
Thanks,
Lorenzo
Quoted 856 lines
Quoted 855 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 5 lines
drivers/pci/host/pcie-designware.c +5
-0+if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller,domain);
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port
Quoted 22 lines
drivers/pci/host/pcie-designware.c +12
-3+#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port*pp,
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus,
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,u32 devfn, int where,
Quoted 25 lines
drivers/pci/host/pcie-designware.c +1
-14static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - }drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 726
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-9- - 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)
Quoted 9 lines
drivers/pci/host/pcie-designware.c +0
-9-{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin)
Quoted 20 lines
drivers/pci/host/pcie-designware.c +0
-17-{ -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;Review
Quoted 1 line
(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 12 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); -------------------------------------------------- --------------------------------------------------Quoted 5 lines
Quoted 5 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han;Pratyush
Quoted 6 lines
Quoted 6 lines
Anand; Arnd Bergmann; [email protected]; Liviu Dudau; linux- [email protected]; [email protected]; [email protected]; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 6 lines
Quoted 6 lines · Gabriele Paoloni
Quoted 3 lines
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve theresources
Quoted 262 lines
Quoted 262 lines
associated to each pci host bridge window.
Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I
have also included all the changes about the other drivers
Quoted 15 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors
about this patch. And I think this patch is a experimental one, it could not
be compiled successfully.Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +4
-2-struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct pci_host_bridge_window *win;This struct is not in latest kernel, I think you should use struct
resource_entry.Thanks,
ZhouQuoted 1 line
+ const
__be32*parser_range_end= of_get_property(np, "ranges",&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get
Quoted 56 lines
* the untranslated address.
drivers/pci/host/pcie-designware.c +7
-41@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp- io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +list_for_each_entry (win, &res, list) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-0+ of_n_addr_cells(np) - 5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */
Quoted 13 lines
drivers/pci/host/pcie-designware.c +9
-4- pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7} } - 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",
Quoted 18 lines
drivers/pci/host/pcie-designware.c +3
-6- 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) {Quoted 1 line
pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, @@-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
if (pp->ops->host_init) pp->ops->host_init(pp);-
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+ if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)drivers/pci/host/pcie-designware.c +2
-1+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Quoted 1 line
+ if (dw_pcie_wr_own_conf(pp,
PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 25 lines
drivers/pci/host/pcie-designware.c +15
-5+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +if (dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain);#else + bus->msi = &dw_pcie_msi_chip;#endif drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 521
Quoted 10 lines
drivers/pci/host/pcie-designware.c +6
-3- dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct
Quoted 7 lines
drivers/pci/host/pcie-designware.c +3
-0+ +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct
pcie_portQuoted 11 lines
Quoted 11 lines
*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where,drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus,u32
Quoted 26 lines
Quoted 26 lines
devfn,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-0int where, int size, u32 val){
- structpcie_port*pp =sys_to_pcie(bus->sysdata);
+ structpcie_port*pp =bus->sysdata;
int ret;if (
dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn))== 0) @@ -701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 17 lines
.write =
dw_pcie_wr_conf,
};drivers/pci/host/pcie-designware.c +0
-14-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;Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
-
pci_add_resource_offset(&sys->resources, &pp->mem, sys- mem_offset);
-pci_add_resource(&sys->resources, &pp->busn);drivers/pci/host/pcie-designware.c +0
-5- -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_dataQuoted 88 lines
Quoted 88 lines
*sys) -{
Quoted 8 lines
- struct
pci_bus*bus;
- structpcie_port*pp =sys_to_pcie(sys);drivers/pci/host/pcie-designware.c +0
-6- - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
Review
Quoted 19 lines
- struct
pcie_port*pp =sys_to_pcie(dev->bus->sysdata);
- int irq;drivers/pci/host/pcie-designware.c +0
-14- - 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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 14 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:[email protected]]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; [email protected]; Liviu Dudau; linux- [email protected]; [email protected]; [email protected]; Gabriele Paoloni; Yuanzhichang;Zhudacai;
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port
Quoted 8 lines
struct of_pci_range_parser parser;drivers/pci/host/pcie-designware.c +2
-0+struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ int dw_pcie_host_init(struct pcie_port*pp)
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 2 lines
Quoted 2 lines
Review int dw_pcie_host_init(struct pcie_port · line 499
Quoted 2 lines
(quoted diff) +0
-0val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,val);
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +10
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port · line 514
Quoted 5 lines
(quoted diff) +5
-0+ global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just
the
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
below arm64 code.
Quoted 2 lines
Quoted 2 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went
as
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we
use
Quoted 2 lines
Quoted 2 lines
a
Quoted 1 line
Quoted 1 line
Quoted 1 line
PCIe device with a I/O Bar, it may not work well without above
code.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
But so far, I have not met a PCIe device which must work with a
I/O
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Bar.
There are two problems here:
1) the
io_baseaddress you get from
of_pci_get_host_bridge_resourcesQuoted 5 lines
Quoted 5 lines
Quoted 1 line
Quoted 1 line
must be mapped using
pci_remap_iospace. You are not doing this,so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work on
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64 works
as
Quoted 11 lines
Quoted 11 lines
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's the valueyou
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and
arm64
Quoted 73 lines
Quoted 73 lines
so,
Quoted 8 lines
Quoted 8 lines
as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port · line 517
Quoted 3 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warningon
Quoted 57 lines
Quoted 57 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp);Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +3
-1-pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
drivers/pci/host/pcie-designware.c +4
-0+#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,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,
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret;Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, · line 695
Quoted 1 line
drivers/pci/host/pcie-designware.c +0
-0if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct
pci_busQuoted 94 lines
Quoted 79 lines
Quoted 45 lines
Quoted 45 lines
*bus, u32 devfn,
Quoted 44 lines
Quoted 11 lines
Quoted 11 lines
int where, int size, u32 val)
{drivers/pci/host/pcie-designware.c +1
-2-struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); -drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10-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);Quoted 17 lines
Quoted 17 lines
drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{drivers/pci/host/pcie-designware.c +0
-10-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 23 lines
Quoted 9 lines
pin) -{
drivers/pci/host/pcie-designware.c +0
-8-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;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 718
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-8-} - -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;.
Quoted 11 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to [email protected] More
majordomo
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
.
.
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 12 lines · Lorenzo Pieralisi
On Tue, Jun 16, 2015 at 03:14:21PM +0100, Gabriele Paoloni wrote:
[...]
Quoted 2 lines
Quoted 2 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 505
Quoted 2 lines
drivers/pci/host/pcie-designware.c +2
-0+ bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res);I think you can't do that on ARM 32-bit platforms. They rely on
pci_sys_datainpcibios_msi_controllerandpcibios_align_resource, if you do not pass apci_sys_datastruct in the sysdata pointer this can't work and unless you get lucky it will explode.
Quoted 6 lines
We have to remove
pci_sys_datadependency on ARM, then this approach will work.Thanks,
Lorenzo
Hi Lorenzo,
For pcibios_align_resource, 1/4 can be used to solve this problem. For pcibios_msi_controller, bus->msi can be set in pcie-designware, then we can get msi controller by dev->bus->msi in pci_msi_controller.
And the latest series is v3 version
"[PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05"
Best regards,
Zhou
Quoted 859 lines
Quoted 847 lines
Quoted 847 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 5 lines
drivers/pci/host/pcie-designware.c +5
-0+if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller,domain);
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port
Quoted 22 lines
drivers/pci/host/pcie-designware.c +12
-3+#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port*pp,
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus,
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,u32 devfn, int where,
Quoted 25 lines
drivers/pci/host/pcie-designware.c +1
-14static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - }drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 726
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-9- - 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)
Quoted 9 lines
drivers/pci/host/pcie-designware.c +0
-9-{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin)
Quoted 20 lines
drivers/pci/host/pcie-designware.c +0
-17-{ -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;Review
Quoted 1 line
(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 12 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); -------------------------------------------------- --------------------------------------------------Quoted 5 lines
Quoted 5 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han;Pratyush
Quoted 6 lines
Quoted 6 lines
Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 6 lines
Quoted 6 lines · Gabriele Paoloni
Quoted 3 lines
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve theresources
Quoted 262 lines
Quoted 262 lines
associated to each pci host bridge window.
Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I
have also included all the changes about the other drivers
Quoted 15 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors
about this patch. And I think this patch is a experimental one, it could not
be compiled successfully.Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +4
-2-struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct pci_host_bridge_window *win;This struct is not in latest kernel, I think you should use struct
resource_entry.Thanks,
ZhouQuoted 1 line
+ const
__be32*parser_range_end= of_get_property(np, "ranges",&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get
Quoted 56 lines
* the untranslated address.
drivers/pci/host/pcie-designware.c +7
-41@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp- io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +list_for_each_entry (win, &res, list) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-0+ of_n_addr_cells(np) - 5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */
Quoted 13 lines
drivers/pci/host/pcie-designware.c +9
-4- pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7} } - 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",
Quoted 18 lines
drivers/pci/host/pcie-designware.c +3
-6- 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) {Quoted 1 line
pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, @@-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
if (pp->ops->host_init) pp->ops->host_init(pp);-
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+ if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)drivers/pci/host/pcie-designware.c +2
-1+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Quoted 1 line
+ if (dw_pcie_wr_own_conf(pp,
PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 25 lines
drivers/pci/host/pcie-designware.c +15
-5+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +if (dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain);#else + bus->msi = &dw_pcie_msi_chip;#endif drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 521
Quoted 10 lines
drivers/pci/host/pcie-designware.c +6
-3- dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct
Quoted 7 lines
drivers/pci/host/pcie-designware.c +3
-0+ +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct
pcie_portQuoted 11 lines
Quoted 11 lines
*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where,drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus,u32
Quoted 26 lines
Quoted 26 lines
devfn,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-0int where, int size, u32 val){
- structpcie_port*pp =sys_to_pcie(bus->sysdata);
+ structpcie_port*pp =bus->sysdata;
int ret;if (
dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn))== 0) @@ -701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 17 lines
.write =
dw_pcie_wr_conf,
};drivers/pci/host/pcie-designware.c +0
-14-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;Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
-
pci_add_resource_offset(&sys->resources, &pp->mem, sys- mem_offset);
-pci_add_resource(&sys->resources, &pp->busn);drivers/pci/host/pcie-designware.c +0
-5- -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_dataQuoted 88 lines
Quoted 88 lines
*sys) -{
Quoted 8 lines
- struct
pci_bus*bus;
- structpcie_port*pp =sys_to_pcie(sys);drivers/pci/host/pcie-designware.c +0
-6- - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
Review
Quoted 19 lines
- struct
pcie_port*pp =sys_to_pcie(dev->bus->sysdata);
- int irq;drivers/pci/host/pcie-designware.c +0
-14- - 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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 14 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang;Zhudacai;
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port
Quoted 8 lines
struct of_pci_range_parser parser;drivers/pci/host/pcie-designware.c +2
-0+struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ int dw_pcie_host_init(struct pcie_port*pp)
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 2 lines
Quoted 2 lines
Review int dw_pcie_host_init(struct pcie_port · line 499
Quoted 2 lines
(quoted diff) +0
-0val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,val);
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +10
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port · line 514
Quoted 5 lines
(quoted diff) +5
-0+ global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just
the
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
below arm64 code.
Quoted 2 lines
Quoted 2 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went
as
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we
use
Quoted 2 lines
Quoted 2 lines
a
Quoted 1 line
Quoted 1 line
Quoted 1 line
PCIe device with a I/O Bar, it may not work well without above
code.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
But so far, I have not met a PCIe device which must work with a
I/O
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Bar.
There are two problems here:
1) the
io_baseaddress you get from
of_pci_get_host_bridge_resourcesQuoted 5 lines
Quoted 5 lines
Quoted 1 line
Quoted 1 line
must be mapped using
pci_remap_iospace. You are not doing this,so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work on
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64 works
as
Quoted 11 lines
Quoted 11 lines
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's the valueyou
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and
arm64
Quoted 73 lines
Quoted 73 lines
so,
Quoted 8 lines
Quoted 8 lines
as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port · line 517
Quoted 3 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warningon
Quoted 57 lines
Quoted 57 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp);Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +3
-1-pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
drivers/pci/host/pcie-designware.c +4
-0+#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,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,
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret;Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, · line 695
Quoted 1 line
drivers/pci/host/pcie-designware.c +0
-0if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct
pci_busQuoted 87 lines
Quoted 87 lines
Quoted 45 lines
Quoted 45 lines
*bus, u32 devfn,
Quoted 44 lines
Quoted 11 lines
Quoted 11 lines
int where, int size, u32 val)
{drivers/pci/host/pcie-designware.c +1
-2-struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); -drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10-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);Quoted 17 lines
Quoted 17 lines
drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{drivers/pci/host/pcie-designware.c +0
-10-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 23 lines
Quoted 9 lines
pin) -{
drivers/pci/host/pcie-designware.c +0
-8-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;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 718
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-8-} - -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;.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to majordomo at vger.kernel.org More
majordomo
Quoted 3 lines
Quoted 2 lines
Quoted 2 lines
Quoted 9 lines
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines
Quoted 2 lines
.
.
.
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 20 lines · Zhou Wang
Quoted 12 lines · Lorenzo Pieralisi
On Tue, Jun 16, 2015 at 03:14:21PM +0100, Gabriele Paoloni wrote:
[...]
Quoted 2 lines
Quoted 2 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 505
Quoted 2 lines
drivers/pci/host/pcie-designware.c +2
-0+ bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res);I think you can't do that on ARM 32-bit platforms. They rely on
pci_sys_datainpcibios_msi_controllerandpcibios_align_resource, if you do not pass apci_sys_datastruct in the sysdata pointer this can't work and unless you get lucky it will explode.Quoted 6 lines
We have to remove
pci_sys_datadependency on ARM, then this approach will work.Thanks,
Lorenzo
Quoted 5 lines
Hi Lorenzo,
For
pcibios_align_resource, 1/4 can be used to solve this problem. Forpcibios_msi_controller,bus->msican be set in pcie-designware, then we can get msi controller bydev->bus->msiinpci_msi_controller.
Yes, 1/4 solves the problem I know, but that's a bit hackish, it would be better if we can create the host bridge and pass it to create_root_bus, that's what Yijing was doing but I am not sure if that's still the plan given his latest series here.
https://patchwork.ozlabs.org/project/linux-pci/list/?submitter=15928
I've just posted a patch for pcibios_msi_controller removal, I did not notice that it was something already put forward by Arnd, anyway those are the last two steps required, let's get them merged.
https://patchwork.ozlabs.org/patch/494498/
Lorenzo
Quoted 872 lines
And the latest series is v3 version
"[PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05"Best regards,
ZhouQuoted 852 lines
Quoted 852 lines
Quoted 852 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 5 lines
drivers/pci/host/pcie-designware.c +5
-0+if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller,domain);
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port
Quoted 22 lines
drivers/pci/host/pcie-designware.c +12
-3+#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port*pp,
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus,
Quoted 9 lines
drivers/pci/host/pcie-designware.c +1
-1static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,u32 devfn, int where,
Quoted 25 lines
drivers/pci/host/pcie-designware.c +1
-14static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - }drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 726
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-9- - 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)
Quoted 9 lines
drivers/pci/host/pcie-designware.c +0
-9-{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin)
Quoted 20 lines
drivers/pci/host/pcie-designware.c +0
-17-{ -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;Review
Quoted 1 line
(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 12 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); -------------------------------------------------- --------------------------------------------------Quoted 5 lines
Quoted 5 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han;Pratyush
Quoted 6 lines
Quoted 6 lines
Anand; Arnd Bergmann; [email protected]; Liviu Dudau; linux- [email protected]; [email protected]; [email protected]; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 6 lines
Quoted 6 lines · Gabriele Paoloni
Quoted 3 lines
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can see I
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve theresources
Quoted 262 lines
Quoted 262 lines
associated to each pci host bridge window.
Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]"; so I
have also included all the changes about the other drivers
Quoted 15 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from Zhou Wang.Quoted 7 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cis gone.I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some format errors
about this patch. And I think this patch is a experimental one, it could not
be compiled successfully.Quoted 12 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +4
-2-struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret; +int rlen; +struct pci_host_bridge_window *win;This struct is not in latest kernel, I think you should use struct
resource_entry.Thanks,
ZhouQuoted 1 line
+ const
__be32*parser_range_end= of_get_property(np, "ranges",&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to get
Quoted 56 lines
* the untranslated address.
drivers/pci/host/pcie-designware.c +7
-41@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (pp->dev,"missing *config* reg space\n" ); } -if (of_pci_range_parser_init (&parser, np)) { -dev_err (pp->dev,"missing ranges property\n" ); -return -EINVAL ; - } + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp- io_base); +if (ret) +return ret;/* Get the I/O and memory ranges from DT */ -for_each_of_pci_range (&parser, &range) { -unsigned long restype = range.flags &IORESOURCE_TYPE_BITS ; - -if (restype ==IORESOURCE_IO ) { -of_pci_range_to_resource (&range, np, &pp->io); - pp->io.name ="I/O" ; - pp->io.start =max_t (resource_size_t, -PCIBIOS_MIN_IO , - range.pci_addr + global_io_offset); - pp->io.end =min_t (resource_size_t, -IO_SPACE_LIMIT , - range.pci_addr + range.size - + global_io_offset -1 ); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==IORESOURCE_MEM ) { -of_pci_range_to_resource (&range, np, &pp->mem); - pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */ - pp->mem_mod_base =of_read_number (parser.range - - parser.np + na, ns); - } -if (restype ==0 ) { -of_pci_range_to_resource (&range, np, &pp->cfg); - pp->cfg0_size =resource_size (&pp->cfg)/2 ; - pp->cfg1_size =resource_size (&pp->cfg)/2 ; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; +list_for_each_entry (win, &res, list) { +switch (resource_type (win->res)) { +case IORESOURCE_IO : + pp->io = win->res;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 397
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ pp->io->name ="I/O" ; + pp->io_size =resource_size (pp->io); + pp->io_bus_addr = pp->io->start - win->offset; +/* magic 5 below comes from magic na and ns in +* of_pci_range_parser_init() */ + pp->io_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failed to mapresource %pR\n",
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+ ret, pp->io); +continue ; + } +break ; +case IORESOURCE_MEM : + pp->mem = win->res; + pp->mem->name ="MEM" ; + pp->mem_size =resource_size (pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + pp->mem_mod_base = of_read_number(parser_range_end -drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-0+ of_n_addr_cells(np) - 5 + na, ns); +break ; +case 0 : + pp->cfg = win->res; + pp->cfg0_size =resource_size (pp->cfg)/2 ; + pp->cfg1_size =resource_size (pp->cfg)/2 ; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size;/* Find the untranslated configuration space address */
Quoted 13 lines
drivers/pci/host/pcie-designware.c +9
-4- pp->cfg0_mod_base =of_read_number (parser.range - - parser.np + na, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number (parser_range_end - +of_n_addr_cells (np) -5 + na, ns); + pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; +break ; +case IORESOURCE_BUS : + pp->busn = win->res; +break ; +default : +continue ;drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7} } - 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",
Quoted 18 lines
drivers/pci/host/pcie-designware.c +3
-6- 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) {Quoted 1 line
pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, @@-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
if (pp->ops->host_init) pp->ops->host_init(pp);-
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+ if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)drivers/pci/host/pcie-designware.c +2
-1+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Quoted 1 line
+ if (dw_pcie_wr_own_conf(pp,
PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 25 lines
drivers/pci/host/pcie-designware.c +15
-5+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; -dw_pcie_rd_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , &val); val |=PORT_LOGIC_SPEED_CHANGE ; -dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val); -#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +if (dw_pcie_wr_own_conf (pp,PCIE_LINK_WIDTH_SPEED_CONTROL ,4 , val) + !=PCIBIOS_SUCCESSFUL ) +return -EINVAL ; + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, +domain);#else + bus->msi = &dw_pcie_msi_chip;#endif drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 521
Quoted 10 lines
drivers/pci/host/pcie-designware.c +6
-3- dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct
Quoted 7 lines
drivers/pci/host/pcie-designware.c +3
-0+ +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct
pcie_portQuoted 11 lines
Quoted 11 lines
*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where,drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct pcie_port *pp,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(structpci_bus*bus,u32
Quoted 26 lines
Quoted 26 lines
devfn,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-0int where, int size, u32 val){
- structpcie_port*pp =sys_to_pcie(bus->sysdata);
+ structpcie_port*pp =bus->sysdata;
int ret;if (
dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn))== 0) @@ -701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 17 lines
.write =
dw_pcie_wr_conf,
};drivers/pci/host/pcie-designware.c +0
-14-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;Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
-
pci_add_resource_offset(&sys->resources, &pp->mem, sys- mem_offset);
-pci_add_resource(&sys->resources, &pp->busn);drivers/pci/host/pcie-designware.c +0
-5- -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_dataQuoted 88 lines
Quoted 88 lines
*sys) -{
Quoted 8 lines
- struct
pci_bus*bus;
- structpcie_port*pp =sys_to_pcie(sys);drivers/pci/host/pcie-designware.c +0
-6- - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10- -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8pin) -{
Review
Quoted 19 lines
- struct
pcie_port*pp =sys_to_pcie(dev->bus->sysdata);
- int irq;drivers/pci/host/pcie-designware.c +0
-14- - 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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 14 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:[email protected]]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; [email protected]; Liviu Dudau; linux- [email protected]; [email protected]; [email protected]; Gabriele Paoloni; Yuanzhichang;Zhudacai;
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportOn Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port
Quoted 8 lines
struct of_pci_range_parser parser;drivers/pci/host/pcie-designware.c +2
-0+struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ int dw_pcie_host_init(struct pcie_port*pp)
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 2 lines
Quoted 2 lines
Review int dw_pcie_host_init(struct pcie_port · line 499
Quoted 2 lines
(quoted diff) +0
-0val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,val);
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +10
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp->io_base); + global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Review int dw_pcie_host_init(struct pcie_port · line 514
Quoted 5 lines
(quoted diff) +5
-0+ global_io_offset - pp->io_bus_addr); + } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); + pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just
the
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
below arm64 code.
Quoted 2 lines
Quoted 2 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went
as
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we
use
Quoted 2 lines
Quoted 2 lines
a
Quoted 1 line
Quoted 1 line
Quoted 1 line
PCIe device with a I/O Bar, it may not work well without above
code.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
But so far, I have not met a PCIe device which must work with a
I/O
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Bar.
There are two problems here:
1) the
io_baseaddress you get from
of_pci_get_host_bridge_resourcesQuoted 5 lines
Quoted 5 lines
Quoted 1 line
Quoted 1 line
must be mapped using
pci_remap_iospace. You are not doing this,so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work on
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64 works
as
Quoted 11 lines
Quoted 11 lines
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's the valueyou
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and
arm64
Quoted 73 lines
Quoted 73 lines
so,
Quoted 8 lines
Quoted 8 lines
as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
LorenzoQuoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review int dw_pcie_host_init(struct pcie_port · line 517
Quoted 3 lines
(quoted diff) +3
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, +&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warningon
Quoted 57 lines
Quoted 57 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct pcie_port · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp);Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +3
-1-pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_valid_config(struct · line 683
Quoted 9 lines
drivers/pci/host/pcie-designware.c +4
-0+#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,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,
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret;Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, · line 695
Quoted 1 line
drivers/pci/host/pcie-designware.c +0
-0if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ){ @@
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct
pci_busQuoted 92 lines
Quoted 90 lines
Quoted 45 lines
Quoted 45 lines
*bus, u32 devfn,
Quoted 44 lines
Quoted 11 lines
Quoted 11 lines
int where, int size, u32 val)
{drivers/pci/host/pcie-designware.c +1
-2-struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, };Quoted 15 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5-static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); -drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-10-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);Quoted 17 lines
Quoted 17 lines
drivers/pci/host/pcie-designware.c +0
-6-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_data*sys) -{drivers/pci/host/pcie-designware.c +0
-10-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 23 lines
Quoted 9 lines
pin) -{
drivers/pci/host/pcie-designware.c +0
-8-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;drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 718
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-8-} - -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;.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to [email protected] More
majordomo
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
.
Quoted 7 lines
Quoted 4 lines
Quoted 3 lines
Quoted 2 lines
.
.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/4 PCI: designware: Add ARM64 support
Quoted 41 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Monday, July 13, 2015 3:18 PM
To: Wangzhou (B)
Cc: Gabriele Paoloni; James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 6 lines · Zhou Wang
Quoted 5 lines · Lorenzo Pieralisi
On Tue, Jun 16, 2015 at 03:14:21PM +0100, Gabriele Paoloni wrote:
[...]
Quoted 1 line
Quoted 1 line
Quoted 1 line
+ bus = pci_create_root_bus(pp->dev,
pp->root_bus_nr,
&dw_pcie_ops,Quoted 3 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
+ pp, &res);
I think you can't do that on ARM 32-bit platforms. They rely on
pci_sys_dataQuoted 2 lines
Quoted 2 lines
in
pcibios_msi_controllerandpcibios_align_resource, if you do not pass apci_sys_datastruct in the sysdata pointer this can't workand
Quoted 3 lines
Quoted 3 lines
unless you get lucky it will explode.
We have to remove
pci_sys_datadependency on ARM, then thisapproach
Quoted 10 lines
Quoted 5 lines
will work.
Thanks,
LorenzoHi Lorenzo,
For
pcibios_align_resource, 1/4 can be used to solve this problem. Forpcibios_msi_controller,bus->msican be set in pcie-designware,then
Quoted 8 lines
Quoted 1 line
we can get msi controller by
dev->bus->msiinpci_msi_controller.Yes, 1/4 solves the problem I know, but that's a bit hackish, it would be better if we can create the host bridge and pass it to
create_root_bus, that's what Yijing was doing but I am not sure if that's still the plan given his latest series here.https://patchwork.ozlabs.org/project/linux-pci/list/?submitter=15928
I have submitted a new patch for this:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/357431.html
Quoted 980 lines
I've just posted a patch for
pcibios_msi_controllerremoval, I did not notice that it was something already put forward by Arnd, anyway those are the last two steps required, let's get them merged.https://patchwork.ozlabs.org/patch/494498/
Lorenzo
Quoted 2 lines
And the latest series is v3 version
"[PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon SocHip05"
Quoted 9 lines
Best regards,
ZhouQuoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 5 lines
drivers/pci/host/pcie-designware.c +5
-0+if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 20 lines
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines
domain);
Quoted 19 lines
drivers/pci/host/pcie-designware.c +12
-3+#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Review static int dw_pcie_valid_config(struct
Quoted 3 lines
return 0;}
(quoted diff) +0
-0@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct
pcie_portQuoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
*pp,
Quoted 1 line
(quoted diff) +0
-0static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, intwhere,
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static int dw_pcie_rd_conf(struct pci_bus
Quoted 8 lines
drivers/pci/host/pcie-designware.c +1
-1int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus*bus,
Quoted 28 lines
Quoted 28 lines
Quoted 28 lines
Quoted 28 lines
u32 devfn, int where,
Quoted 27 lines
drivers/pci/host/pcie-designware.c +1
-16static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-7-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_dataQuoted 9 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
*sys)
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-7-{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys-resources);
Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c +0
-4-if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
pin)
Quoted 20 lines
drivers/pci/host/pcie-designware.c +0
-17-{ -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;Review
Quoted 1 line
(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 12 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); -------------------------------------------------- --------------------------------------------------Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
-----Original Message-----
From: Wangzhou (B)
Sent: Thursday, June 11, 2015 6:44 AM
To: Gabriele Paoloni
Cc: Lorenzo Pieralisi; James Morse; Bjorn Helgaas; Jingoo Han;Pratyush
Quoted 1 line
Quoted 1 line
Anand; Arnd Bergmann; fabrice.gasnier at st.com; Liviu Dudau;
linux-
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64 supportQuoted 3 lines · Gabriele Paoloni
Hi Zhou Wang and all
I have worked on a patch that unify ARM and ARM64. As you can
see I
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
have removed the parser and now I use "
of_pci_get_host_bridge_resources" in order to retrieve theresources
Quoted 2 lines
Quoted 2 lines
associated to each pci host bridge window.
Quoted 1 line
The resources now are not copied to the designware
pcie_portpp,
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
instead they are passed by pointer.
Quoted 2 lines
This patch is intended to replace entirely "[PATCH v2 2/4]";
so I
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
have also included all the changes about the other drivers
Quoted 7 lines
Please find the patch inline below.
Let me know if you think it is ok.
Regards
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Gab
------------------------------------
------------------------------------This patch is a rework of
"[PATCH v2 2/4] PCI: designware: Add ARM64 support" from ZhouWang.
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
The intention is to complete the unification between ARM and ARM64 now that the dependency on
arch/arm/kernel/bios32.cisgone.
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 5 lines
I have also included the rework asked by James Morse:
io_basedeclared asresource_size_tIt compiles fine on ARCH arm and arm64.
Hi Gabriele,
I manually apply this patch on my series, as there are some
format
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
errors
about this patch. And I think this patch is a experimental one,it
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
could not
be compiled successfully.Quoted 16 lines
It needs to be tested.
Signed-off-by Gabriele Paoloni <[email protected]>[...]
drivers/pci/host/pcie-designware.c +2
-3-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev); -struct of_pci_range range; -struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
+
LIST_HEAD(res);
u32 val, na, ns;
const__be32*addrp;
int i, index, ret;
+ int rlen;
+ structpci_host_bridge_window*win;This struct is not in latest kernel, I think you should use
struct
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
resource_entry.Thanks,
ZhouQuoted 1 line
+ const
__be32*parser_range_end= of_get_property(np,"ranges",
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
&rlen);
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 7 lines
drivers/pci/host/pcie-designware.c +5
-0+ +if (parser_range_end ==NULL ) +return -ENOENT ; + parser_range_end += rlen/sizeof (__be32); +/* Find the address cell size and the number of cells in order to
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
get
Review int dw_pcie_host_init(struct pcie_port
Quoted 2 lines
* the untranslated address.
(quoted diff) +0
-0@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port*pp)
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 8 lines
drivers/pci/host/pcie-designware.c +1
-4dev_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-
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 7 lines
drivers/pci/host/pcie-designware.c +2
-2io_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;Quoted 8 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +0
-3- -if (restype ==IORESOURCE_IO ) { - of_pci_range_to_resource(&range, np, &pp-io);
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c +0
-4- pp->io.name ="I/O" ; - pp->io.start = max_t(resource_size_t, - PCIBIOS_MIN_IO, - range.pci_addr +
global_io_offset);Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +0
-3- pp->io.end = min_t(resource_size_t, - IO_SPACE_LIMIT, - range.pci_addr +range.size
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-7- + global_io_offset - 1); - pp->io_size =resource_size (&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - -/* Find the untranslated IO space address */ - pp->io_mod_base =of_read_number(parser.range -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 404
Quoted 1 line
(quoted diff) +0
-1- parser.np +na, ns);
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +0
-3- } -if (restype ==IORESOURCE_MEM ) { - of_pci_range_to_resource(&range, np, &pp-mem);
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5- pp->mem.name ="MEM" ; - pp->mem_size =resource_size (&pp->mem); - pp->mem_bus_addr = range.pci_addr; - -/* Find the untranslated MEM space address */
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 413
Quoted 1 line
(quoted diff) +0
-1- pp->mem_mod_base =of_read_number(parser.range -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 414
Quoted 1 line
(quoted diff) +0
-1- parser.np+ na, ns);
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +0
-3- } -if (restype ==0 ) { - of_pci_range_to_resource(&range, np, &pp-cfg);
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +0
-4- 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;Quoted 9 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 7 lines
drivers/pci/host/pcie-designware.c +7
-0+list_for_each_entry (win, &res, list) { +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;
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
(quoted diff) +1
-0+ /* magic 5 below comes from magic na and nsin
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 392
Quoted 1 line
(quoted diff) +1
-0+ * of_pci_range_parser_init()*/
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 393
Quoted 1 line
(quoted diff) +1
-0+ pp->io_mod_base =of_read_number(parser_range_end -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 394
Quoted 1 line
(quoted diff) +1
-0+ of_n_addr_cells(np) - 5 + na,ns);
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +3
-0+ ret =pci_remap_iospace (pp->io, pp->io_base); +if (ret) { + dev_warn(pp->dev, "error %d: failedto map
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
resource %pR\n",
Quoted 9 lines
drivers/pci/host/pcie-designware.c +9
-0+ 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-Quoted 2 lines
offset;
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
(quoted diff) +1
-0+ pp->mem_mod_base =of_read_number(parser_range_end -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 408
Quoted 1 line
(quoted diff) +1
-0+ of_n_addr_cells(np) - 5 + na,ns);
Quoted 10 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 7 lines
drivers/pci/host/pcie-designware.c +7
-0+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;Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
(quoted diff) +0
-0/* Find the untranslated configuration spaceaddress
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
*/
Quoted 1 line
(quoted diff) +0
-1- pp->cfg0_mod_base =of_read_number(parser.range -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 424
Quoted 1 line
(quoted diff) +0
-1- parser.np+ na, ns);
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +1
-2- pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + pp->cfg0_mod_base =of_read_number(parser_range_end -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 418
Quoted 1 line
(quoted diff) +1
-0+ of_n_addr_cells(np) - 5 + na,ns);
Quoted 18 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct pcie_port · line 419
Quoted 1 line
(quoted diff) +1
-0+ pp->cfg1_mod_base = pp->cfg0_mod_base + pp-
cfg0_size;Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
drivers/pci/host/pcie-designware.c +6
-7+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-rangeproperty: %d,
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
using default %pR\n",
Quoted 14 lines
drivers/pci/host/pcie-designware.c +2
-5- 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 ; } }Quoted 29 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 5 lines
drivers/pci/host/pcie-designware.c +1
-1- 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, @@Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
-493,24 +482,47 @@ int
dw_pcie_host_init(struct pcie_port *pp)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 10 lines
if (pp->ops->host_init) pp->ops->host_init(pp);-
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+ if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)drivers/pci/host/pcie-designware.c +2
-1+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ;/* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI);Quoted 1 line
+ if (dw_pcie_wr_own_conf(pp,
PCI_CLASS_DEVICE, 2,
PCI_CLASS_BRIDGE_PCI)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +2
-1+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; - dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,&val);
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
val |=
PORT_LOGIC_SPEED_CHANGE;
- dw_pcie_wr_own_conf(pp,PCIE_LINK_WIDTH_SPEED_CONTROL, 4,val);
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
-#ifdef
CONFIG_PCI_MSI
- dw_pcie_msi_chip.dev =pp->dev;
- dw_pci.msi_ctrl =&dw_pcie_msi_chip;
+ if (dw_pcie_wr_own_conf(pp,PCIE_LINK_WIDTH_SPEED_CONTROL, 4,val)
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 4 lines
drivers/pci/host/pcie-designware.c +4
-0+ != PCIBIOS_SUCCESSFUL) +return -EINVAL ; + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c +2
-0+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 521
Quoted 10 lines
drivers/pci/host/pcie-designware.c +6
-3- dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Quoted 4 lines
+
+pci_assign_unassigned_bus_resources(bus);
+pci_bus_add_devices(bus);Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Review static int dw_pcie_valid_config(struct
Quoted 3 lines
return 0;
}(quoted diff) +0
-0@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct
pcie_portQuoted 1 line
Quoted 1 line
*pp, static int dw_pcie_rd_conf(struct
pci_bus*bus, u32 devfn,int
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
where,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +1
-1int 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 ){ @@ -
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
677,7 +689,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus,u32
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
devfn, int where, static int dw_pcie_wr_conf(struct
pci_bus*bus,
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
u32
Quoted 8 lines
Quoted 8 lines
devfn,
Quoted 7 lines
drivers/pci/host/pcie-designware.c +0
-0int where, int size, u32 val){
- structpcie_port*pp =sys_to_pcie(bus->sysdata);
+ structpcie_port*pp =bus->sysdata;
int ret;if (
dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn))== 0) @@-
Quoted 35 lines
Quoted 27 lines
Quoted 27 lines
Quoted 27 lines
Quoted 18 lines
Quoted 18 lines
701,64 +713,6 @@ static struct
pci_opsdw_pcie_ops= {Quoted 17 lines
.write =
dw_pcie_wr_conf,
};drivers/pci/host/pcie-designware.c +0
-14-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;Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
-
pci_add_resource_offset(&sys->resources, &pp->mem, sys- mem_offset);
-pci_add_resource(&sys->resources, &pp->busn);drivers/pci/host/pcie-designware.c +0
-5- -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
pci_sys_dataQuoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
*sys) -{
Quoted 6 lines
- struct
pci_bus*bus;
- structpcie_port*pp =sys_to_pcie(sys);drivers/pci/host/pcie-designware.c +0
-4- - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys-resources);
Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
- if (!bus)
drivers/pci/host/pcie-designware.c +0
-3-return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -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
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
pin) -{
Review
Quoted 19 lines
- struct
pcie_port*pp =sys_to_pcie(dev->bus->sysdata);
- int irq;drivers/pci/host/pcie-designware.c +0
-14- - 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;(quoted diff) +0
-0
b/drivers/pci/host/pcie-designware.hReview
Quoted 28 lines
index d0bbd27..ab78710 100644
drivers/pci/host/pcie-designware.h +5
-5@@ -34,7 +34,7 @@ struct pcie_port {u64 cfg1_mod_base;void __iomem *va_cfg1_base;u32 cfg1_size; -u64 io_base; +resource_size_t io_base;u64 io_mod_base;phys_addr_t io_bus_addr;u32 io_size;@@ -42,10 +42,10 @@ struct pcie_port {u64 mem_mod_base;phys_addr_t mem_bus_addr;u32 mem_size; -struct resource cfg; -struct resource io; -struct resource mem; -struct resource busn; +struct resource *cfg; +struct resource *io; +struct resource *mem; +struct resource *busn;int irq;u32 lanes;struct pcie_host_ops *ops;(quoted diff) +0
-0
b/drivers/pci/host/pcie-spear13xx.cdrivers/pci/host/pcie-spear13xx.c static int spear13xx_add_pcie_port(struct
Quoted 4 lines
index 020d788..e78ddf8 100644
drivers/pci/host/pcie-spear13xx.c +0
-0@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct
pcie_port*pp,Quoted 14 lines
drivers/pci/host/pcie-spear13xx.c +1
-3return ret; } - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ; pp->ops = &spear13xx_pcie_host_ops; ret =dw_pcie_host_init (pp); ------------------------------------ ------------------------------------Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
-----Original Message-----
From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
Sent: Tuesday, June 09, 2015 12:15 PM
To: Wangzhou (B)
Cc: James Morse; Bjorn Helgaas; Jingoo Han; Pratyush Anand;Arnd
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Bergmann; fabrice.gasnier at st.com; Liviu Dudau; linux- pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; Gabriele Paoloni; Yuanzhichang;
Zhudacai;
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
Subject: Re: [PATCH v2 2/4] PCI: designware: Add ARM64support
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines · Zhou Wang
[...]
Quoted 5 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c static const struct irq_domain_ops msi_domain_ops = {
Quoted 5 lines
drivers/pci/host/pcie-designware.c +1
-1-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node; struct platform_device *pdev =
to_platform_device(pp->dev);Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct
Quoted 9 lines
struct of_pci_range range; struct of_pci_range_parser parser;drivers/pci/host/pcie-designware.c +2
-0+struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ int dw_pcie_host_init(struct
pcie_portQuoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
*pp)
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
(quoted diff) +0
-0val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp,
PCIE_LINK_WIDTH_SPEED_CONTROL, 4,Quoted 17 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
val);
Quoted 12 lines
Quoted 12 lines
Review int dw_pcie_host_init(struct · line 507
Quoted 12 lines
(quoted diff) +8
-3-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM + /* + * FIXME: we should really be able to use + * of_pci_get_host_bridge_resources on arm32 as well, + * but the conversion needs some more testing + */ + if (global_io_offset < SZ_1M && pp->io_size > 0) { + pci_ioremap_io(global_io_offset, pp-
io_base);Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
(quoted diff) +3
-0+ global_io_offset += SZ_64K; + pci_add_resource_offset(&res, &pp->io, + global_io_offset -
pp->io_bus_addr);Quoted 7 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Review int dw_pcie_host_init(struct · line 513
Quoted 3 lines
(quoted diff) +3
-0+ } + pci_add_resource_offset(&res, &pp->mem, + pp->mem.start - pp-
mem_bus_addr);Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Review int dw_pcie_host_init(struct · line 514
Quoted 1 line
(quoted diff) +1
-0+ pci_add_resource(&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of
'the
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
conversion needs some more testing', I removed it leaving
just
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
the
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
below arm64 code.
Quoted 2 lines
Quoted 2 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I
went
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
as
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if
we
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
use
Quoted 2 lines
Quoted 2 lines
a
Quoted 1 line
Quoted 1 line
Quoted 1 line
PCIe device with a I/O Bar, it may not work well without
above
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
code.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
But so far, I have not met a PCIe device which must work
with a
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
I/O
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Bar.
There are two problems here:
1) the
io_baseaddress you get from
of_pci_get_host_bridge_resourcesQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
must be mapped using
pci_remap_iospace. You are not doingthis,
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
so
Quoted 1 line
Quoted 1 line
even if you had a PCIe card with I/O bar it would not work
on
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
arm64
Quoted 1 line
Quoted 1 line
as the code stands. Remember that I/O space on arm/arm64
works
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
as
Quoted 2 lines
Quoted 2 lines
a
Quoted 1 line
Quoted 1 line
memory access with offset from
PCI_IOBASEand that's thevalue
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 9 lines
Quoted 9 lines
you
Quoted 8 lines
Quoted 8 lines
get
in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c2) (1) above would sort out I/O space access for both arm and
arm64
Quoted 3 lines
Quoted 3 lines
so,
Quoted 2 lines
Quoted 2 lines
as James said, the #ifdef is useless.
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
I hope this makes things clearer.
Thanks,
LorenzoQuoted 3 lines
Quoted 3 lines
Quoted 3 lines
(quoted diff) +2
-0+#else + ret = of_pci_get_host_bridge_resources(np, 0, 0xff,&res,
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Review int dw_pcie_host_init(struct · line 517
Quoted 1 line
(quoted diff) +1
-0+&pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto bea
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
resource_size_t*, but
&io_baseis u64*. This generates awarning
Quoted 37 lines
Quoted 37 lines
Quoted 37 lines
Quoted 37 lines
Quoted 37 lines
Quoted 37 lines
on
Quoted 36 lines
Quoted 36 lines
Quoted 11 lines
Quoted 8 lines
arm with the above change. Changing the the type in
drivers/pci/host/pcie-designware.hfixes this.Thanks,
James
OK, will modify this in next version.
Quoted 7 lines
Best Regards and thanks again for your test, Zhou
Quoted 5 lines
Review int dw_pcie_host_init(struct · line 522
Quoted 5 lines
(quoted diff) +5
-0+ if (ret) + return ret; +#endif + + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
&dw_pcie_ops,Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 6 lines
drivers/pci/host/pcie-designware.c +6
-0+ pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct
msi_controller,Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c +5
-2+domain); #else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp);Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp)
Quoted 3 lines
drivers/pci/host/pcie-designware.c +2
-1-pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 1 line
Quoted 1 line
Review int dw_pcie_host_init(struct · line 539
Quoted 1 line
(quoted diff) +1
-0+ pci_fixup_irqs(pci_common_swizzle,
of_irq_parse_and_map_pci);Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/pci/host/pcie-designware.c +4
-0+#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,7 @@ static int dw_pcie_valid_config(struct
pcie_port*pp, static int dw_pcie_rd_conf(structpci_bus*bus,
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
u32 devfn, int where,
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
int size, u32 *val){
drivers/pci/host/pcie-designware.c +1
-1-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)
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
{ @@
Quoted 1 line
Quoted 1 line
Quoted 1 line
-677,7 +707,7 @@ static int dw_pcie_rd_conf(struct
pci_bus*bus,
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
u32 devfn, int where, static int dw_pcie_wr_conf(struct
pci_busQuoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
*bus, u32 devfn,
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
int where, int size, u32 val)
{drivers/pci/host/pcie-designware.c +1
-1-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) @@
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
-701,64 +731,6 @@ static struct
pci_opsdw_pcie_ops= {
.write =dw_pcie_wr_conf,
};-static int
dw_pcie_setup(int nr, struct pci_sys_data *sys)-{
Quoted 11 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 6 lines
drivers/pci/host/pcie-designware.c +0
-6-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;Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
- pci_ioremap_io(global_io_offset, pp-
io_base);Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
(quoted diff) +0
-2- global_io_offset += SZ_64K; - pci_add_resource_offset(&sys->resources,
&pp->io,Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5- sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; - pci_add_resource_offset(&sys->resources, &pp->mem,sys-
Quoted 15 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
mem_offset);Quoted 5 lines
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-5-pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} -Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
-static struct
pci_bus*dw_pcie_scan_bus(int nr, structpci_sys_data*sys) -{drivers/pci/host/pcie-designware.c +0
-6-struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_create_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys-resources);
Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/pci/host/pcie-designware.c +0
-4-if (!bus) -return NULL ; - -pci_scan_child_bus (bus);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = {
Quoted 8 lines
drivers/pci/host/pcie-designware.c +0
-8- -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8slot,
Quoted 29 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
u8
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
pin) -{
- structpcie_port*pp = sys_to_pcie(dev->bus-sysdata);
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 12 lines
Quoted 12 lines
drivers/pci/host/pcie-designware.c +0
-12-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,Quoted 9 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 718
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-3- .map_irq = dw_pcie_map_irq, -}; -void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;.
--
To unsubscribe from this list: send the line "unsubscribelinux-
Quoted 16 lines
Quoted 16 lines
Quoted 15 lines
Quoted 14 lines
Quoted 13 lines
Quoted 9 lines
pci"
Quoted 1 line
Quoted 1 line
Quoted 1 line
in the body of a message to majordomo at vger.kernel.org More
majordomo
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines
.
.
Quoted 6 lines
Quoted 2 lines
.
--
To unsubscribe from this list: send the line "unsubscribe devicetree"in
Quoted 3 lines
the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/4 PCI: designware: Add ARM64 support
In reply to Lorenzo PieralisiQuoted 64 lines · Lorenzo Pieralisi
On Fri, Jun 05, 2015 at 09:11:30AM +0100, Zhou Wang wrote:
[...]
Quoted 39 lines
Quoted 39 lines
Quoted 25 lines
drivers/pci/host/pcie-designware.c +8
-4-int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ 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 - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 515
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the below arm64 code.
Quoted 7 lines
Quoted 3 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
I think it depends on which kind of PCIe device you use, if we use a PCIe device with a I/O Bar, it may not work well without above code. But so far, I have not met a PCIe device which must work with a I/O Bar.
There are two problems here:
1) the
io_baseaddress you get fromof_pci_get_host_bridge_resourcesmust be mapped usingpci_remap_iospace. You are not doing this, so even if you had a PCIe card with I/O bar it would not work on arm64 as the code stands. Remember that I/O space on arm/arm64 works as a memory access with offset fromPCI_IOBASEand that's the value you get in the I/O resource. See:
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pci-xgene.c
Quoted 8 lines
2) (1) above would sort out I/O space access for both arm and arm64 so, as James said, the #ifdef is useless.
I hope this makes things clearer.
Thanks,
Lorenzo
Hi Lorenzo,
Many thanks for your explanation. I have a better understanding now. So I think we could remove #ifdef and add pci_remap_iospace after of_pci_get_host_bridge_resources.
Regards,
Zhou
Quoted 149 lines
Quoted 141 lines
Quoted 10 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 3 lines
drivers/pci/host/pcie-designware.c +2
-0+#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warning on arm with the above change. Changing the the type indrivers/pci/host/pcie-designware.hfixes this.Quoted 4 lines
Thanks,
James
OK, will modify this in next version.
Best Regards and thanks again for your test,
ZhouQuoted 110 lines
Quoted 110 lines
drivers/pci/host/pcie-designware.c +25
-61+if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +707,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; -pci_add_resource_offset (&sys->resources, &pp->mem, sys->mem_offset); -pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus (int nr,struct pci_sys_data *sys) -{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pcie_port *pp =sys_to_pcie (dev->bus->sysdata); -int irq; - - irq =of_irq_parse_and_map_pci (dev, slot, pin); -if (!irq) - irq = pp->irq; - -return irq; -} - -static struct hw_pci dw_pci = { - .setup = dw_pcie_setup, - .scan = dw_pcie_scan_bus, - .map_irq = dw_pcie_map_irq,Quoted 9 lines
drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 736
Quoted 5 lines
drivers/pci/host/pcie-designware.c +0
-2-}; -void dw_pcie_setup_rc (struct pcie_port *pp) {u32 val;.
Quoted 5 lines
--
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.
PATCH v2 2/4 PCI: designware: Add ARM64 support
In reply to James MorseQuoted 127 lines · James Morse
Quoted 12 lines · 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_irqand structhw_pci, move related operations todw_pcie_host_init. Also setpp->root_bus_nr= 0 in each PCIe host driver which is based on pcie-designware.I am not very clear about I/O resource management:
Quoted 6 lines
if (global_io_offset < SZ_1M && pp->io_size > 0) { pci_ioremap_io(global_io_offset, pp->io_base); global_io_offset += SZ_64K; pci_add_resource_offset(&res, &pp->io, global_io_offset - pp->io_bus_addr); }Quoted 5 lines
so just move steps in
dw_pcie_setuptodw_pcie_host_init.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.I have tested this on a 'Freescale i.MX6 Quad SABRE Lite Board', which also uses a designware pcie host controller (
PCI_IMX6). Booted, removed/rescanned the bus, then scanned for wireless access points using the b43 driver. Please note my change below.Tested-by James Morse <[email protected]>Quoted 87 lines
drivers/pci/host/pcie-designware.c +13
-15@@ -11,6 +11,7 @@* published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -67,17 +68,10 @@#define PCIE_ATU_FUNC (x) (((x) & 0x7) << 16)#define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; +static struct pci_ops dw_pcie_ops;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; -} -int dw_pcie_cfg_read (void __iomem *addr,int where,int size,u32 *val) { *val =readl (addr);@@ -238,7 +232,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)static int assign_irq (int no_irqs,struct msi_desc *desc,int *pos) {int irq, pos0, i; -struct pcie_port *pp =sys_to_pcie (desc->dev->bus->sysdata); +struct pcie_port *pp = desc->dev->bus->sysdata; pos0 =bitmap_find_free_region (pp->msi_irq_in_use,MAX_MSI_IRQS ,order_base_2 (no_irqs));@@ -281,7 +275,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, {int irq, pos;struct msi_msg msg; -struct pcie_port *pp =sys_to_pcie (pdev->bus->sysdata); +struct pcie_port *pp = pdev->bus->sysdata;if (desc->msi_attrib.is_msix)return -EINVAL ;@@ -310,7 +304,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) {struct irq_data *data =irq_get_irq_data (irq);struct msi_desc *msi =irq_data_get_msi (data); -struct pcie_port *pp =sys_to_pcie (msi->dev->bus->sysdata); +struct pcie_port *pp = msi->dev->bus->sysdata;clear_irq_range (pp, irq,1 , data->hwirq); }@@ -342,13 +336,15 @@ static const struct irq_domain_ops msi_domain_ops = { .map = dw_pcie_msi_map, }; -int dw_pcie_host_init (struct pcie_port *pp) +int __init dw_pcie_host_init (struct pcie_port *pp) {struct device_node *np = pp->dev->of_node;struct platform_device *pdev =to_platform_device (pp->dev);struct of_pci_range range;struct of_pci_range_parser parser; +struct pci_bus *bus;struct resource *cfg_res; +LIST_HEAD (res);u32 val, na, ns;const __be32 *addrp;int i, index, ret;@@ -502,15 +498,49 @@ 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 - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 515
Quoted 10 lines
drivers/pci/host/pcie-designware.c +10
-0+*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn);I don't think this #ifdef is necessary. In the spirit of 'the conversion needs some more testing', I removed it leaving just the below arm64 code.
Quoted 4 lines
This worked on my Freescale i.MX6 Quad SABRE Lite Board, I went as far as scanning for wireless access points.
Hi James,
I think you are right. We can remove #ifdef as of_pci_get_host_bridge_resources also manages mem, io and bus resources.
And just as Lorenzo said, if we want PCIe cards with IO bar work well, pci_remap_iospace should be added after of_pci_get_host_bridge_resources to map IO cpu address to PCI_IOBASE.
Thanks again for your test :)
Zhou
Quoted 132 lines
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 517
Quoted 2 lines
drivers/pci/host/pcie-designware.c +2
-0+#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base);
of_pci_get_host_bridge_resourcesexpects&pp->io_baseto be a resource_size_t*, but&io_baseis u64*. This generates a warning on arm with the above change. Changing the the type indrivers/pci/host/pcie-designware.hfixes this.Thanks,
James
Quoted 105 lines
drivers/pci/host/pcie-designware.c +25
-56+if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus) + pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);return 0 ; }@@ -653,7 +683,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,static int dw_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 ) {@@ -677,7 +707,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,static int dw_pcie_wr_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 val) { -struct pcie_port *pp =sys_to_pcie (bus->sysdata); +struct pcie_port *pp = bus->sysdata;int ret;if (dw_pcie_valid_config (pp, bus,PCI_SLOT (devfn)) ==0 )@@ -701,64 +731,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup (int nr,struct pci_sys_data *sys) -{ -struct pcie_port *pp; - - pp =sys_to_pcie (sys); - -if (global_io_offset <SZ_1M && pp->io_size >0 ) { - sys->io_offset = global_io_offset - pp->io_bus_addr; -pci_ioremap_io (global_io_offset, pp->io_base); - global_io_offset +=SZ_64K ; -pci_add_resource_offset (&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; -pci_add_resource_offset (&sys->resources, &pp->mem, sys->mem_offset); -pci_add_resource (&sys->resources, &pp->busn); - -return 1 ; -} - -static struct pci_bus *dw_pcie_scan_bus (int nr,struct pci_sys_data *sys) -{ -struct pci_bus *bus; -struct pcie_port *pp =sys_to_pcie (sys); - - pp->root_bus_nr = sys->busnr; - bus =pci_create_root_bus (pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); -if (!bus) -return NULL ; - -pci_scan_child_bus (bus); - -if (bus && pp->ops->scan_bus) - pp->ops->scan_bus (pp); - -return bus; -} - -static int dw_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pcie_port *pp =sys_to_pcie (dev->bus->sysdata); -int irq; - - irq =of_irq_parse_and_map_pci (dev, slot, pin); -if (!irq) - irq = pp->irq; - -return irq; -}drivers/pci/host/pcie-designware.c static struct pci_ops dw_pcie_ops = { · line 736
Quoted 10 lines
drivers/pci/host/pcie-designware.c +0
-7- -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;.
PATCH v2 2/4 PCI: designware: Add ARM64 support
In reply to Zhou WangHi Zhou Wang,
Thanks for unifying arm and arm64 code.
Quoted 7 lines · 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_irqand structhw_pci, move related operations todw_pcie_host_init. Also setpp->root_bus_nr= 0 in each PCIe host driver which is based on pcie-designware.I am not very clear about I/O resource management:
Following discussion may help to understand it, specially in the context of designware.
http://marc.info/?l=linux-pci&m=138621989417562&w=2
Quoted 24 lines
Quoted 6 lines
if (global_io_offset < SZ_1M && pp->io_size > 0) { pci_ioremap_io(global_io_offset, pp->io_base); global_io_offset += SZ_64K; pci_add_resource_offset(&res, &pp->io, global_io_offset - pp->io_bus_addr); }so just move steps in
dw_pcie_setuptodw_pcie_host_init.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 <[email protected]>Tested-by Fabrice Gasnier <[email protected]>--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 128 +++++++++++++++---------------------- drivers/pci/host/pcie-spear13xx.c | 2 +- 7 files changed, 56 insertions(+), 83 deletions(-)
[...]
drivers/pci/host/pci-layerscape.c static int ls_add_pcie_port(struct ls_pcie *pcie) · line 104
Quoted 10 lines
drivers/pci/host/pci-layerscape.c +1
-1@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ;
similar change for pcie-spear13xx.c should be needed as well.
Quoted 7 lines
drivers/pci/host/pci-layerscape.c +0
-0pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pcie-designware.c +0
-0
[...]
Quoted 39 lines
drivers/pci/host/pcie-designware.c +32
-5-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing +*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn); +#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base); +if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus)
drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 543
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-1+ pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);
As James and Lorenzo has suggested, of_pci_get_host_bridge_resources should work for ARM as well. I would suggest to move that just after cfg resource parsing and
then to remove following piece of code. for_each_of_pci_range(&parser, &range) {
...
}
ret = of_pci_parse_bus_range(np, &pp->busn);
Then you can have a loop like
list_for_each_entry(entry, &res, node) {
struct resource *res_temp = entry->res;
if (resource_type(res_temp) == IORESOURCE_IO) {
} else if (resource_type(res_temp) == IORESOURCE_MEM) {
}
}where you can fill, xx_size, xx_bus_addr, xx_mod_base etc. You can also remove global_io_offset variable.
~Pratyush
PATCH v2 2/4 PCI: designware: Add ARM64 support
Hi Pratyush,
sorry for late.
Quoted 11 lines · Pratyush Anand
Hi Zhou Wang,
Thanks for unifying arm and arm64 code.
Quoted 6 lines · 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_irqand structhw_pci, move related operations todw_pcie_host_init. Also setpp->root_bus_nr= 0 in each PCIe host driver which is based on pcie-designware.
Quoted 6 lines
Quoted 1 line
I am not very clear about I/O resource management:
Following discussion may help to understand it, specially in the context of designware.
Thanks for sharing above information.
Quoted 29 lines
Quoted 26 lines
Quoted 8 lines
if (global_io_offset < SZ_1M && pp->io_size > 0) { pci_ioremap_io(global_io_offset, pp->io_base); global_io_offset += SZ_64K; pci_add_resource_offset(&res, &pp->io, global_io_offset - pp->io_bus_addr); }so just move steps in
dw_pcie_setuptodw_pcie_host_init.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 <[email protected]>Tested-by Fabrice Gasnier <[email protected]>--- drivers/pci/host/pci-dra7xx.c | 1 + drivers/pci/host/pci-exynos.c | 2 +- drivers/pci/host/pci-imx6.c | 2 +- drivers/pci/host/pci-keystone.c | 2 +- drivers/pci/host/pci-layerscape.c | 2 +- drivers/pci/host/pcie-designware.c | 128 +++++++++++++++---------------------- drivers/pci/host/pcie-spear13xx.c | 2 +- 7 files changed, 56 insertions(+), 83 deletions(-)[...]
Quoted 13 lines
drivers/pci/host/pci-layerscape.c static int ls_add_pcie_port(struct ls_pcie *pcie) · line 104
Quoted 10 lines
drivers/pci/host/pci-layerscape.c +1
-1@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr =-1 ; + pp->root_bus_nr =0 ;similar change for
pcie-spear13xx.cshould be needed as well.
Right, will add this in next version.
Quoted 71 lines
Quoted 7 lines
drivers/pci/host/pci-layerscape.c +0
-0pp->ops = &ls_pcie_host_ops; ret =dw_pcie_host_init (pp);drivers/pci/host/pcie-designware.c +0
-0[...]
Quoted 39 lines
drivers/pci/host/pcie-designware.c +32
-5-#ifdef CONFIG_PCI_MSI - dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; +#ifdef CONFIG_ARM +/* +* FIXME: we should really be able to use +* of_pci_get_host_bridge_resources on arm32 as well, +* but the conversion needs some more testing +*/ +if (global_io_offset <SZ_1M && pp->io_size >0 ) { +pci_ioremap_io (global_io_offset, pp->io_base); + global_io_offset +=SZ_64K ; +pci_add_resource_offset (&res, &pp->io, + global_io_offset - pp->io_bus_addr); + } +pci_add_resource_offset (&res, &pp->mem, + pp->mem.start - pp->mem_bus_addr); +pci_add_resource (&res, &pp->busn); +#else + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base); +if (ret) +return ret; +#endif + + bus =pci_create_root_bus (pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); +if (!bus) +return -ENOMEM ; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else + bus->msi = &dw_pcie_msi_chip;#endif - dw_pci.nr_controllers =1 ; - dw_pci.private_data = (void **)&pp; +pci_scan_child_bus (bus); +if (pp->ops->scan_bus)drivers/pci/host/pcie-designware.c int dw_pcie_host_init(struct pcie_port *pp) · line 543
Quoted 10 lines
drivers/pci/host/pcie-designware.c +8
-1+ pp->ops->scan_bus (pp); -pci_common_init_dev (pp->dev, &dw_pci); +#ifdef CONFIG_ARM +/* support old dtbs that incorrectly describe IRQs */ +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +#endif + +pci_assign_unassigned_bus_resources (bus); +pci_bus_add_devices (bus);As James and Lorenzo has suggested,
of_pci_get_host_bridge_resourcesshould work for ARM as well. I would suggest to move that just after cfg resource parsing and
then to remove following piece of code.for_each_of_pci_range(&parser, &range){
...
}
ret =of_pci_parse_bus_range(np, &pp->busn);Then you can have a loop like
Quoted 8 lines
list_for_each_entry(entry, &res, node) { struct resource *res_temp = entry->res; if (resource_type(res_temp) == IORESOURCE_IO) { } else if (resource_type(res_temp) == IORESOURCE_MEM) { } }where you can fill,
xx_size,xx_bus_addr,xx_mod_baseetc.
I think it will be better to do like this. And Gabriele already shared a patch about this in this series'discussions, I will try to merge his patch in my next version patchset.
Quoted 1 line
You can also remove
global_io_offsetvariable.
will use pci_remap_iospace in next version patch.
Many thanks for your comments
Zhou
Quoted 9 lines
~Pratyush
--
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.
PATCH v2 3/4 PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
In reply to Zhou WangThis patch adds PCIe host support for Hisilicon Soc Hip05.
--- drivers/pci/host/Kconfig | 5 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pcie-hisi.c | 258 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 drivers/pci/host/pcie-hisi.c
drivers/pci/host/Kconfig +5 -0
@@ -125,4 +125,9 @@ config PCIE_IPROC_PLATFORM Say Y here if you want to use the Broadcom iProc PCIe controller through the generic platform bus interface +config PCI_HISI + depends on OF && ARM64 + bool "Hisilicon Soc HIP05 PCIe controller" + select PCIE_DW + endmenu
drivers/pci/host/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o +obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
drivers/pci/host/pcie-hisi.c new file +258 -0
258 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 3/4 PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
drivers/pci/host/pcie-hisi.c
Quoted 5 lines · Zhou Wang
drivers/pci/host/pcie-hisi.c new file +0
-0
New file? Please update MAINTAINERS.
(Also add your new Documentation file in patch 4/4 with that patch)
Thanks,
James
PATCH v2 3/4 PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
Quoted 11 lines · James Morse
drivers/pci/host/pcie-hisi.c
Quoted 5 lines · Zhou Wang
drivers/pci/host/pcie-hisi.c new file +0
-0New file? Please update
MAINTAINERS.
(Also add your new Documentation file in patch 4/4 with that patch)
Quoted 3 lines
Thanks,
James
Ok, wil add this patch next version.
Thanks,
ZHou
Quoted 7 lines
--
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.
PATCH v2 4/4 Documentation: DT: Add Hisilicon PCIe host binding
In reply to Zhou WangThis patch adds related DTS binding document for Hisilicon PCIe host driver.
--- .../devicetree/bindings/pci/hisilicon-pcie.txt | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
Documentation/devicetree/bindings/pci/hisilicon-pcie.txt new file +46 -0
@@ -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"; + };
Signature · 1 line
1.9.1