* [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2019-10-28 22:51 Rob Herring
2019-10-30 14:51 ` kbuild test robot
[not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
0 siblings, 2 replies; 13+ messages in thread
From: Rob Herring @ 2019-10-28 22:51 UTC (permalink / raw)
To: linux-pci
Cc: Thierry Reding, Lorenzo Pieralisi, Andrew Murray, Bjorn Helgaas,
Jonathan Hunter, linux-tegra
Convert Tegra PCI host driver to use the common
pci_parse_request_of_pci_ranges().
This allows removing the DT ranges parsing, PCI resource handling, and
private storage of resources from the driver.
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Andrew Murray <andrew.murray@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>
---
Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
dependent on my prior series, specifically this patch[1].
Compile tested only.
Rob
[1] https://patchwork.ozlabs.org/patch/1185555/
drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
1 file changed, 46 insertions(+), 141 deletions(-)
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 673a1725ef38..83d8209a372a 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -355,16 +355,6 @@ struct tegra_pcie {
int irq;
struct resource cs;
- struct resource io;
- struct resource pio;
- struct resource mem;
- struct resource prefetch;
- struct resource busn;
-
- struct {
- resource_size_t mem;
- resource_size_t io;
- } offset;
struct clk *pex_clk;
struct clk *afi_clk;
@@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
-static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
-{
- struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
- struct list_head *windows = &host->windows;
- struct device *dev = pcie->dev;
- int err;
-
- pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
- pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
- pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
- pci_add_resource(windows, &pcie->busn);
-
- err = devm_request_pci_bus_resources(dev, windows);
- if (err < 0) {
- pci_free_resource_list(windows);
- return err;
- }
-
- pci_remap_iospace(&pcie->pio, pcie->io.start);
-
- return 0;
-}
-
-static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
-{
- struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
- struct list_head *windows = &host->windows;
-
- pci_unmap_iospace(&pcie->pio);
- pci_free_resource_list(windows);
-}
-
static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
struct tegra_pcie *pcie = pdev->bus->sysdata;
@@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
*/
static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
{
- u32 fpci_bar, size, axi_address;
+ u32 size;
+ struct resource_entry *entry;
+ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
/* Bar 0: type 1 extended configuration space */
size = resource_size(&pcie->cs);
afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
- /* Bar 1: downstream IO bar */
- fpci_bar = 0xfdfc0000;
- size = resource_size(&pcie->io);
- axi_address = pcie->io.start;
- afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
- afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
- afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
-
- /* Bar 2: prefetchable memory BAR */
- fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
- size = resource_size(&pcie->prefetch);
- axi_address = pcie->prefetch.start;
- afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
- afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
- afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
-
- /* Bar 3: non prefetchable memory BAR */
- fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
- size = resource_size(&pcie->mem);
- axi_address = pcie->mem.start;
- afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
- afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
- afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
+ resource_list_for_each_entry(entry, &bridge->windows) {
+ u32 fpci_bar, axi_address;
+ struct resource *res = entry->res;
+
+ size = resource_size(res);
+
+ switch (resource_type(res)) {
+ case IORESOURCE_IO:
+ /* Bar 1: downstream IO bar */
+ fpci_bar = 0xfdfc0000;
+ axi_address = pci_pio_to_address(res->start);
+ afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
+ break;
+ case IORESOURCE_MEM:
+ fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
+ axi_address = res->start;
+
+ if (res->flags & IORESOURCE_PREFETCH) {
+ /* Bar 2: prefetchable memory BAR */
+ afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
+
+ } else {
+ /* Bar 3: non prefetchable memory BAR */
+ afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
+ }
+ break;
+ }
+ }
/* NULL out the remaining BARs as they are not used */
afi_writel(pcie, 0, AFI_AXI_BAR4_START);
@@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
struct device *dev = pcie->dev;
struct device_node *np = dev->of_node, *port;
const struct tegra_pcie_soc *soc = pcie->soc;
- struct of_pci_range_parser parser;
- struct of_pci_range range;
u32 lanes = 0, mask = 0;
unsigned int lane = 0;
- struct resource res;
int err;
- if (of_pci_range_parser_init(&parser, np)) {
- dev_err(dev, "missing \"ranges\" property\n");
- return -EINVAL;
- }
-
- for_each_of_pci_range(&parser, &range) {
- err = of_pci_range_to_resource(&range, np, &res);
- if (err < 0)
- return err;
-
- switch (res.flags & IORESOURCE_TYPE_BITS) {
- case IORESOURCE_IO:
- /* Track the bus -> CPU I/O mapping offset. */
- pcie->offset.io = res.start - range.pci_addr;
-
- memcpy(&pcie->pio, &res, sizeof(res));
- pcie->pio.name = np->full_name;
-
- /*
- * The Tegra PCIe host bridge uses this to program the
- * mapping of the I/O space to the physical address,
- * so we override the .start and .end fields here that
- * of_pci_range_to_resource() converted to I/O space.
- * We also set the IORESOURCE_MEM type to clarify that
- * the resource is in the physical memory space.
- */
- pcie->io.start = range.cpu_addr;
- pcie->io.end = range.cpu_addr + range.size - 1;
- pcie->io.flags = IORESOURCE_MEM;
- pcie->io.name = "I/O";
-
- memcpy(&res, &pcie->io, sizeof(res));
- break;
-
- case IORESOURCE_MEM:
- /*
- * Track the bus -> CPU memory mapping offset. This
- * assumes that the prefetchable and non-prefetchable
- * regions will be the last of type IORESOURCE_MEM in
- * the ranges property.
- * */
- pcie->offset.mem = res.start - range.pci_addr;
-
- if (res.flags & IORESOURCE_PREFETCH) {
- memcpy(&pcie->prefetch, &res, sizeof(res));
- pcie->prefetch.name = "prefetchable";
- } else {
- memcpy(&pcie->mem, &res, sizeof(res));
- pcie->mem.name = "non-prefetchable";
- }
- break;
- }
- }
-
- err = of_pci_parse_bus_range(np, &pcie->busn);
- if (err < 0) {
- dev_err(dev, "failed to parse ranges property: %d\n", err);
- pcie->busn.name = np->name;
- pcie->busn.start = 0;
- pcie->busn.end = 0xff;
- pcie->busn.flags = IORESOURCE_BUS;
- }
-
/* parse root ports */
for_each_child_of_node(np, port) {
struct tegra_pcie_port *rp;
@@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
struct pci_host_bridge *host;
struct tegra_pcie *pcie;
struct pci_bus *child;
+ struct resource *bus;
int err;
host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
@@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&pcie->ports);
pcie->dev = dev;
+ err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
+ if (err) {
+ dev_err(dev, "Getting bridge resources failed\n");
+ return err;
+ }
+
err = tegra_pcie_parse_dt(pcie);
if (err < 0)
return err;
@@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
goto teardown_msi;
}
- err = tegra_pcie_request_resources(pcie);
- if (err)
- goto pm_runtime_put;
-
- host->busnr = pcie->busn.start;
+ host->busnr = bus->start;
host->dev.parent = &pdev->dev;
host->ops = &tegra_pcie_ops;
host->map_irq = tegra_pcie_map_irq;
@@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
err = pci_scan_root_bus_bridge(host);
if (err < 0) {
dev_err(dev, "failed to register host: %d\n", err);
- goto free_resources;
+ goto pm_runtime_put;
}
pci_bus_size_bridges(host->bus);
@@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
return 0;
-free_resources:
- tegra_pcie_free_resources(pcie);
pm_runtime_put:
pm_runtime_put_sync(pcie->dev);
pm_runtime_disable(pcie->dev);
@@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
pci_stop_root_bus(host->bus);
pci_remove_root_bus(host->bus);
- tegra_pcie_free_resources(pcie);
pm_runtime_put_sync(pcie->dev);
pm_runtime_disable(pcie->dev);
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2019-10-30 14:51 ` kbuild test robot
[not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
1 sibling, 0 replies; 13+ messages in thread
From: kbuild test robot @ 2019-10-30 14:51 UTC (permalink / raw)
To: Rob Herring
Cc: kbuild-all, linux-pci, Thierry Reding, Lorenzo Pieralisi,
Andrew Murray, Bjorn Helgaas, Jonathan Hunter, linux-tegra
[-- Attachment #1: Type: text/plain, Size: 4348 bytes --]
Hi Rob,
I love your patch! Yet something to improve:
[auto build test ERROR on tegra/for-next]
[also build test ERROR on v5.4-rc5 next-20191030]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Rob-Herring/PCI-tegra-Use-pci_parse_request_of_pci_ranges/20191030-211825
base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-14) 7.4.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/pci/controller/pci-tegra.c: In function 'tegra_pcie_probe':
>> drivers/pci/controller/pci-tegra.c:2689:8: error: too many arguments to function 'pci_parse_request_of_pci_ranges'
err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/of_pci.h:5:0,
from drivers/pci/controller/pci-tegra.c:30:
include/linux/pci.h:2279:5: note: declared here
int pci_parse_request_of_pci_ranges(struct device *dev,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/pci_parse_request_of_pci_ranges +2689 drivers/pci/controller/pci-tegra.c
2667
2668 static int tegra_pcie_probe(struct platform_device *pdev)
2669 {
2670 struct device *dev = &pdev->dev;
2671 struct pci_host_bridge *host;
2672 struct tegra_pcie *pcie;
2673 struct pci_bus *child;
2674 struct resource *bus;
2675 int err;
2676
2677 host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
2678 if (!host)
2679 return -ENOMEM;
2680
2681 pcie = pci_host_bridge_priv(host);
2682 host->sysdata = pcie;
2683 platform_set_drvdata(pdev, pcie);
2684
2685 pcie->soc = of_device_get_match_data(dev);
2686 INIT_LIST_HEAD(&pcie->ports);
2687 pcie->dev = dev;
2688
> 2689 err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
2690 if (err) {
2691 dev_err(dev, "Getting bridge resources failed\n");
2692 return err;
2693 }
2694
2695 err = tegra_pcie_parse_dt(pcie);
2696 if (err < 0)
2697 return err;
2698
2699 err = tegra_pcie_get_resources(pcie);
2700 if (err < 0) {
2701 dev_err(dev, "failed to request resources: %d\n", err);
2702 return err;
2703 }
2704
2705 err = tegra_pcie_msi_setup(pcie);
2706 if (err < 0) {
2707 dev_err(dev, "failed to enable MSI support: %d\n", err);
2708 goto put_resources;
2709 }
2710
2711 pm_runtime_enable(pcie->dev);
2712 err = pm_runtime_get_sync(pcie->dev);
2713 if (err) {
2714 dev_err(dev, "fail to enable pcie controller: %d\n", err);
2715 goto teardown_msi;
2716 }
2717
2718 host->busnr = bus->start;
2719 host->dev.parent = &pdev->dev;
2720 host->ops = &tegra_pcie_ops;
2721 host->map_irq = tegra_pcie_map_irq;
2722 host->swizzle_irq = pci_common_swizzle;
2723
2724 err = pci_scan_root_bus_bridge(host);
2725 if (err < 0) {
2726 dev_err(dev, "failed to register host: %d\n", err);
2727 goto pm_runtime_put;
2728 }
2729
2730 pci_bus_size_bridges(host->bus);
2731 pci_bus_assign_resources(host->bus);
2732
2733 list_for_each_entry(child, &host->bus->children, node)
2734 pcie_bus_configure_settings(child);
2735
2736 pci_bus_add_devices(host->bus);
2737
2738 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
2739 err = tegra_pcie_debugfs_init(pcie);
2740 if (err < 0)
2741 dev_err(dev, "failed to setup debugfs: %d\n", err);
2742 }
2743
2744 return 0;
2745
2746 pm_runtime_put:
2747 pm_runtime_put_sync(pcie->dev);
2748 pm_runtime_disable(pcie->dev);
2749 teardown_msi:
2750 tegra_pcie_msi_teardown(pcie);
2751 put_resources:
2752 tegra_pcie_put_resources(pcie);
2753 return err;
2754 }
2755
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70204 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2019-10-30 14:51 ` kbuild test robot
0 siblings, 0 replies; 13+ messages in thread
From: kbuild test robot @ 2019-10-30 14:51 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 4476 bytes --]
Hi Rob,
I love your patch! Yet something to improve:
[auto build test ERROR on tegra/for-next]
[also build test ERROR on v5.4-rc5 next-20191030]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Rob-Herring/PCI-tegra-Use-pci_parse_request_of_pci_ranges/20191030-211825
base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-14) 7.4.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/pci/controller/pci-tegra.c: In function 'tegra_pcie_probe':
>> drivers/pci/controller/pci-tegra.c:2689:8: error: too many arguments to function 'pci_parse_request_of_pci_ranges'
err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/of_pci.h:5:0,
from drivers/pci/controller/pci-tegra.c:30:
include/linux/pci.h:2279:5: note: declared here
int pci_parse_request_of_pci_ranges(struct device *dev,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/pci_parse_request_of_pci_ranges +2689 drivers/pci/controller/pci-tegra.c
2667
2668 static int tegra_pcie_probe(struct platform_device *pdev)
2669 {
2670 struct device *dev = &pdev->dev;
2671 struct pci_host_bridge *host;
2672 struct tegra_pcie *pcie;
2673 struct pci_bus *child;
2674 struct resource *bus;
2675 int err;
2676
2677 host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
2678 if (!host)
2679 return -ENOMEM;
2680
2681 pcie = pci_host_bridge_priv(host);
2682 host->sysdata = pcie;
2683 platform_set_drvdata(pdev, pcie);
2684
2685 pcie->soc = of_device_get_match_data(dev);
2686 INIT_LIST_HEAD(&pcie->ports);
2687 pcie->dev = dev;
2688
> 2689 err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
2690 if (err) {
2691 dev_err(dev, "Getting bridge resources failed\n");
2692 return err;
2693 }
2694
2695 err = tegra_pcie_parse_dt(pcie);
2696 if (err < 0)
2697 return err;
2698
2699 err = tegra_pcie_get_resources(pcie);
2700 if (err < 0) {
2701 dev_err(dev, "failed to request resources: %d\n", err);
2702 return err;
2703 }
2704
2705 err = tegra_pcie_msi_setup(pcie);
2706 if (err < 0) {
2707 dev_err(dev, "failed to enable MSI support: %d\n", err);
2708 goto put_resources;
2709 }
2710
2711 pm_runtime_enable(pcie->dev);
2712 err = pm_runtime_get_sync(pcie->dev);
2713 if (err) {
2714 dev_err(dev, "fail to enable pcie controller: %d\n", err);
2715 goto teardown_msi;
2716 }
2717
2718 host->busnr = bus->start;
2719 host->dev.parent = &pdev->dev;
2720 host->ops = &tegra_pcie_ops;
2721 host->map_irq = tegra_pcie_map_irq;
2722 host->swizzle_irq = pci_common_swizzle;
2723
2724 err = pci_scan_root_bus_bridge(host);
2725 if (err < 0) {
2726 dev_err(dev, "failed to register host: %d\n", err);
2727 goto pm_runtime_put;
2728 }
2729
2730 pci_bus_size_bridges(host->bus);
2731 pci_bus_assign_resources(host->bus);
2732
2733 list_for_each_entry(child, &host->bus->children, node)
2734 pcie_bus_configure_settings(child);
2735
2736 pci_bus_add_devices(host->bus);
2737
2738 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
2739 err = tegra_pcie_debugfs_init(pcie);
2740 if (err < 0)
2741 dev_err(dev, "failed to setup debugfs: %d\n", err);
2742 }
2743
2744 return 0;
2745
2746 pm_runtime_put:
2747 pm_runtime_put_sync(pcie->dev);
2748 pm_runtime_disable(pcie->dev);
2749 teardown_msi:
2750 tegra_pcie_msi_teardown(pcie);
2751 put_resources:
2752 tegra_pcie_put_resources(pcie);
2753 return err;
2754 }
2755
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 70204 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2020-02-21 14:20 ` Lorenzo Pieralisi
[not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
1 sibling, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-21 14:20 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding, Andrew Murray,
Bjorn Helgaas, Jonathan Hunter,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
>
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
>
> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
>
> Compile tested only.
>
> Rob
>
> [1] https://patchwork.ozlabs.org/patch/1185555/
>
> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> 1 file changed, 46 insertions(+), 141 deletions(-)
Patch still applies, I need testing and ACK from Tegra maintainers
please.
Thanks,
Lorenzo
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
> int irq;
>
> struct resource cs;
> - struct resource io;
> - struct resource pio;
> - struct resource mem;
> - struct resource prefetch;
> - struct resource busn;
> -
> - struct {
> - resource_size_t mem;
> - resource_size_t io;
> - } offset;
>
> struct clk *pex_clk;
> struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> - struct device *dev = pcie->dev;
> - int err;
> -
> - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> - pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> - pci_add_resource(windows, &pcie->busn);
> -
> - err = devm_request_pci_bus_resources(dev, windows);
> - if (err < 0) {
> - pci_free_resource_list(windows);
> - return err;
> - }
> -
> - pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> - return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> -
> - pci_unmap_iospace(&pcie->pio);
> - pci_free_resource_list(windows);
> -}
> -
> static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
> {
> struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
> */
> static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
> {
> - u32 fpci_bar, size, axi_address;
> + u32 size;
> + struct resource_entry *entry;
> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>
> /* Bar 0: type 1 extended configuration space */
> size = resource_size(&pcie->cs);
> afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
> afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>
> - /* Bar 1: downstream IO bar */
> - fpci_bar = 0xfdfc0000;
> - size = resource_size(&pcie->io);
> - axi_address = pcie->io.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> - /* Bar 2: prefetchable memory BAR */
> - fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->prefetch);
> - axi_address = pcie->prefetch.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> - /* Bar 3: non prefetchable memory BAR */
> - fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->mem);
> - axi_address = pcie->mem.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + resource_list_for_each_entry(entry, &bridge->windows) {
> + u32 fpci_bar, axi_address;
> + struct resource *res = entry->res;
> +
> + size = resource_size(res);
> +
> + switch (resource_type(res)) {
> + case IORESOURCE_IO:
> + /* Bar 1: downstream IO bar */
> + fpci_bar = 0xfdfc0000;
> + axi_address = pci_pio_to_address(res->start);
> + afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> + break;
> + case IORESOURCE_MEM:
> + fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> + axi_address = res->start;
> +
> + if (res->flags & IORESOURCE_PREFETCH) {
> + /* Bar 2: prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> + } else {
> + /* Bar 3: non prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + }
> + break;
> + }
> + }
>
> /* NULL out the remaining BARs as they are not used */
> afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
> struct device *dev = pcie->dev;
> struct device_node *np = dev->of_node, *port;
> const struct tegra_pcie_soc *soc = pcie->soc;
> - struct of_pci_range_parser parser;
> - struct of_pci_range range;
> u32 lanes = 0, mask = 0;
> unsigned int lane = 0;
> - struct resource res;
> int err;
>
> - if (of_pci_range_parser_init(&parser, np)) {
> - dev_err(dev, "missing \"ranges\" property\n");
> - return -EINVAL;
> - }
> -
> - for_each_of_pci_range(&parser, &range) {
> - err = of_pci_range_to_resource(&range, np, &res);
> - if (err < 0)
> - return err;
> -
> - switch (res.flags & IORESOURCE_TYPE_BITS) {
> - case IORESOURCE_IO:
> - /* Track the bus -> CPU I/O mapping offset. */
> - pcie->offset.io = res.start - range.pci_addr;
> -
> - memcpy(&pcie->pio, &res, sizeof(res));
> - pcie->pio.name = np->full_name;
> -
> - /*
> - * The Tegra PCIe host bridge uses this to program the
> - * mapping of the I/O space to the physical address,
> - * so we override the .start and .end fields here that
> - * of_pci_range_to_resource() converted to I/O space.
> - * We also set the IORESOURCE_MEM type to clarify that
> - * the resource is in the physical memory space.
> - */
> - pcie->io.start = range.cpu_addr;
> - pcie->io.end = range.cpu_addr + range.size - 1;
> - pcie->io.flags = IORESOURCE_MEM;
> - pcie->io.name = "I/O";
> -
> - memcpy(&res, &pcie->io, sizeof(res));
> - break;
> -
> - case IORESOURCE_MEM:
> - /*
> - * Track the bus -> CPU memory mapping offset. This
> - * assumes that the prefetchable and non-prefetchable
> - * regions will be the last of type IORESOURCE_MEM in
> - * the ranges property.
> - * */
> - pcie->offset.mem = res.start - range.pci_addr;
> -
> - if (res.flags & IORESOURCE_PREFETCH) {
> - memcpy(&pcie->prefetch, &res, sizeof(res));
> - pcie->prefetch.name = "prefetchable";
> - } else {
> - memcpy(&pcie->mem, &res, sizeof(res));
> - pcie->mem.name = "non-prefetchable";
> - }
> - break;
> - }
> - }
> -
> - err = of_pci_parse_bus_range(np, &pcie->busn);
> - if (err < 0) {
> - dev_err(dev, "failed to parse ranges property: %d\n", err);
> - pcie->busn.name = np->name;
> - pcie->busn.start = 0;
> - pcie->busn.end = 0xff;
> - pcie->busn.flags = IORESOURCE_BUS;
> - }
> -
> /* parse root ports */
> for_each_child_of_node(np, port) {
> struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> struct pci_host_bridge *host;
> struct tegra_pcie *pcie;
> struct pci_bus *child;
> + struct resource *bus;
> int err;
>
> host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> INIT_LIST_HEAD(&pcie->ports);
> pcie->dev = dev;
>
> + err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> + if (err) {
> + dev_err(dev, "Getting bridge resources failed\n");
> + return err;
> + }
> +
> err = tegra_pcie_parse_dt(pcie);
> if (err < 0)
> return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> goto teardown_msi;
> }
>
> - err = tegra_pcie_request_resources(pcie);
> - if (err)
> - goto pm_runtime_put;
> -
> - host->busnr = pcie->busn.start;
> + host->busnr = bus->start;
> host->dev.parent = &pdev->dev;
> host->ops = &tegra_pcie_ops;
> host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> err = pci_scan_root_bus_bridge(host);
> if (err < 0) {
> dev_err(dev, "failed to register host: %d\n", err);
> - goto free_resources;
> + goto pm_runtime_put;
> }
>
> pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>
> return 0;
>
> -free_resources:
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put:
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>
> pci_stop_root_bus(host->bus);
> pci_remove_root_bus(host->bus);
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-21 14:20 ` Lorenzo Pieralisi
0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-21 14:20 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci, Thierry Reding, Andrew Murray, Bjorn Helgaas,
Jonathan Hunter, linux-tegra
On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
>
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Andrew Murray <andrew.murray@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
>
> Compile tested only.
>
> Rob
>
> [1] https://patchwork.ozlabs.org/patch/1185555/
>
> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> 1 file changed, 46 insertions(+), 141 deletions(-)
Patch still applies, I need testing and ACK from Tegra maintainers
please.
Thanks,
Lorenzo
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
> int irq;
>
> struct resource cs;
> - struct resource io;
> - struct resource pio;
> - struct resource mem;
> - struct resource prefetch;
> - struct resource busn;
> -
> - struct {
> - resource_size_t mem;
> - resource_size_t io;
> - } offset;
>
> struct clk *pex_clk;
> struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> - struct device *dev = pcie->dev;
> - int err;
> -
> - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> - pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> - pci_add_resource(windows, &pcie->busn);
> -
> - err = devm_request_pci_bus_resources(dev, windows);
> - if (err < 0) {
> - pci_free_resource_list(windows);
> - return err;
> - }
> -
> - pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> - return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> -
> - pci_unmap_iospace(&pcie->pio);
> - pci_free_resource_list(windows);
> -}
> -
> static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
> {
> struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
> */
> static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
> {
> - u32 fpci_bar, size, axi_address;
> + u32 size;
> + struct resource_entry *entry;
> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>
> /* Bar 0: type 1 extended configuration space */
> size = resource_size(&pcie->cs);
> afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
> afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>
> - /* Bar 1: downstream IO bar */
> - fpci_bar = 0xfdfc0000;
> - size = resource_size(&pcie->io);
> - axi_address = pcie->io.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> - /* Bar 2: prefetchable memory BAR */
> - fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->prefetch);
> - axi_address = pcie->prefetch.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> - /* Bar 3: non prefetchable memory BAR */
> - fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->mem);
> - axi_address = pcie->mem.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + resource_list_for_each_entry(entry, &bridge->windows) {
> + u32 fpci_bar, axi_address;
> + struct resource *res = entry->res;
> +
> + size = resource_size(res);
> +
> + switch (resource_type(res)) {
> + case IORESOURCE_IO:
> + /* Bar 1: downstream IO bar */
> + fpci_bar = 0xfdfc0000;
> + axi_address = pci_pio_to_address(res->start);
> + afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> + break;
> + case IORESOURCE_MEM:
> + fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> + axi_address = res->start;
> +
> + if (res->flags & IORESOURCE_PREFETCH) {
> + /* Bar 2: prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> + } else {
> + /* Bar 3: non prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + }
> + break;
> + }
> + }
>
> /* NULL out the remaining BARs as they are not used */
> afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
> struct device *dev = pcie->dev;
> struct device_node *np = dev->of_node, *port;
> const struct tegra_pcie_soc *soc = pcie->soc;
> - struct of_pci_range_parser parser;
> - struct of_pci_range range;
> u32 lanes = 0, mask = 0;
> unsigned int lane = 0;
> - struct resource res;
> int err;
>
> - if (of_pci_range_parser_init(&parser, np)) {
> - dev_err(dev, "missing \"ranges\" property\n");
> - return -EINVAL;
> - }
> -
> - for_each_of_pci_range(&parser, &range) {
> - err = of_pci_range_to_resource(&range, np, &res);
> - if (err < 0)
> - return err;
> -
> - switch (res.flags & IORESOURCE_TYPE_BITS) {
> - case IORESOURCE_IO:
> - /* Track the bus -> CPU I/O mapping offset. */
> - pcie->offset.io = res.start - range.pci_addr;
> -
> - memcpy(&pcie->pio, &res, sizeof(res));
> - pcie->pio.name = np->full_name;
> -
> - /*
> - * The Tegra PCIe host bridge uses this to program the
> - * mapping of the I/O space to the physical address,
> - * so we override the .start and .end fields here that
> - * of_pci_range_to_resource() converted to I/O space.
> - * We also set the IORESOURCE_MEM type to clarify that
> - * the resource is in the physical memory space.
> - */
> - pcie->io.start = range.cpu_addr;
> - pcie->io.end = range.cpu_addr + range.size - 1;
> - pcie->io.flags = IORESOURCE_MEM;
> - pcie->io.name = "I/O";
> -
> - memcpy(&res, &pcie->io, sizeof(res));
> - break;
> -
> - case IORESOURCE_MEM:
> - /*
> - * Track the bus -> CPU memory mapping offset. This
> - * assumes that the prefetchable and non-prefetchable
> - * regions will be the last of type IORESOURCE_MEM in
> - * the ranges property.
> - * */
> - pcie->offset.mem = res.start - range.pci_addr;
> -
> - if (res.flags & IORESOURCE_PREFETCH) {
> - memcpy(&pcie->prefetch, &res, sizeof(res));
> - pcie->prefetch.name = "prefetchable";
> - } else {
> - memcpy(&pcie->mem, &res, sizeof(res));
> - pcie->mem.name = "non-prefetchable";
> - }
> - break;
> - }
> - }
> -
> - err = of_pci_parse_bus_range(np, &pcie->busn);
> - if (err < 0) {
> - dev_err(dev, "failed to parse ranges property: %d\n", err);
> - pcie->busn.name = np->name;
> - pcie->busn.start = 0;
> - pcie->busn.end = 0xff;
> - pcie->busn.flags = IORESOURCE_BUS;
> - }
> -
> /* parse root ports */
> for_each_child_of_node(np, port) {
> struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> struct pci_host_bridge *host;
> struct tegra_pcie *pcie;
> struct pci_bus *child;
> + struct resource *bus;
> int err;
>
> host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> INIT_LIST_HEAD(&pcie->ports);
> pcie->dev = dev;
>
> + err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> + if (err) {
> + dev_err(dev, "Getting bridge resources failed\n");
> + return err;
> + }
> +
> err = tegra_pcie_parse_dt(pcie);
> if (err < 0)
> return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> goto teardown_msi;
> }
>
> - err = tegra_pcie_request_resources(pcie);
> - if (err)
> - goto pm_runtime_put;
> -
> - host->busnr = pcie->busn.start;
> + host->busnr = bus->start;
> host->dev.parent = &pdev->dev;
> host->ops = &tegra_pcie_ops;
> host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> err = pci_scan_root_bus_bridge(host);
> if (err < 0) {
> dev_err(dev, "failed to register host: %d\n", err);
> - goto free_resources;
> + goto pm_runtime_put;
> }
>
> pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>
> return 0;
>
> -free_resources:
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put:
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>
> pci_stop_root_bus(host->bus);
> pci_remove_root_bus(host->bus);
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
2020-02-21 14:20 ` Lorenzo Pieralisi
@ 2020-02-22 17:36 ` Vidya Sagar
-1 siblings, 0 replies; 13+ messages in thread
From: Vidya Sagar @ 2020-02-22 17:36 UTC (permalink / raw)
To: Lorenzo Pieralisi, Rob Herring
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding, Andrew Murray,
Bjorn Helgaas, Jonathan Hunter,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> External email: Use caution opening links or attachments
>
>
> On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
>> Convert Tegra PCI host driver to use the common
>> pci_parse_request_of_pci_ranges().
>>
>> This allows removing the DT ranges parsing, PCI resource handling, and
>> private storage of resources from the driver.
>>
>> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
>> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> ---
>> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
>> dependent on my prior series, specifically this patch[1].
>>
>> Compile tested only.
>>
>> Rob
>>
>> [1] https://patchwork.ozlabs.org/patch/1185555/
>>
>> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>> 1 file changed, 46 insertions(+), 141 deletions(-)
>
> Patch still applies, I need testing and ACK from Tegra maintainers
> please.
I tested this patch on Jetson-TX1 with NVMe drive connected to it.
Verified basic enumeration and functionality of the drive.
Tested-by: Vidya Sagar <vidyas-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Thanks,
Vidya Sagar
>
> Thanks,
> Lorenzo
>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 673a1725ef38..83d8209a372a 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -355,16 +355,6 @@ struct tegra_pcie {
>> int irq;
>>
>> struct resource cs;
>> - struct resource io;
>> - struct resource pio;
>> - struct resource mem;
>> - struct resource prefetch;
>> - struct resource busn;
>> -
>> - struct {
>> - resource_size_t mem;
>> - resource_size_t io;
>> - } offset;
>>
>> struct clk *pex_clk;
>> struct clk *afi_clk;
>> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>>
>> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
>> -{
>> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> - struct list_head *windows = &host->windows;
>> - struct device *dev = pcie->dev;
>> - int err;
>> -
>> - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
>> - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
>> - pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
>> - pci_add_resource(windows, &pcie->busn);
>> -
>> - err = devm_request_pci_bus_resources(dev, windows);
>> - if (err < 0) {
>> - pci_free_resource_list(windows);
>> - return err;
>> - }
>> -
>> - pci_remap_iospace(&pcie->pio, pcie->io.start);
>> -
>> - return 0;
>> -}
>> -
>> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
>> -{
>> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> - struct list_head *windows = &host->windows;
>> -
>> - pci_unmap_iospace(&pcie->pio);
>> - pci_free_resource_list(windows);
>> -}
>> -
>> static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>> {
>> struct tegra_pcie *pcie = pdev->bus->sysdata;
>> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>> */
>> static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>> {
>> - u32 fpci_bar, size, axi_address;
>> + u32 size;
>> + struct resource_entry *entry;
>> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>>
>> /* Bar 0: type 1 extended configuration space */
>> size = resource_size(&pcie->cs);
>> afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>> afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>>
>> - /* Bar 1: downstream IO bar */
>> - fpci_bar = 0xfdfc0000;
>> - size = resource_size(&pcie->io);
>> - axi_address = pcie->io.start;
>> - afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> - afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> -
>> - /* Bar 2: prefetchable memory BAR */
>> - fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> - size = resource_size(&pcie->prefetch);
>> - axi_address = pcie->prefetch.start;
>> - afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> - afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> -
>> - /* Bar 3: non prefetchable memory BAR */
>> - fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> - size = resource_size(&pcie->mem);
>> - axi_address = pcie->mem.start;
>> - afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> - afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> + resource_list_for_each_entry(entry, &bridge->windows) {
>> + u32 fpci_bar, axi_address;
>> + struct resource *res = entry->res;
>> +
>> + size = resource_size(res);
>> +
>> + switch (resource_type(res)) {
>> + case IORESOURCE_IO:
>> + /* Bar 1: downstream IO bar */
>> + fpci_bar = 0xfdfc0000;
>> + axi_address = pci_pio_to_address(res->start);
>> + afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> + afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> + break;
>> + case IORESOURCE_MEM:
>> + fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
>> + axi_address = res->start;
>> +
>> + if (res->flags & IORESOURCE_PREFETCH) {
>> + /* Bar 2: prefetchable memory BAR */
>> + afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> + afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> +
>> + } else {
>> + /* Bar 3: non prefetchable memory BAR */
>> + afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> + afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> + }
>> + break;
>> + }
>> + }
>>
>> /* NULL out the remaining BARs as they are not used */
>> afi_writel(pcie, 0, AFI_AXI_BAR4_START);
>> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>> struct device *dev = pcie->dev;
>> struct device_node *np = dev->of_node, *port;
>> const struct tegra_pcie_soc *soc = pcie->soc;
>> - struct of_pci_range_parser parser;
>> - struct of_pci_range range;
>> u32 lanes = 0, mask = 0;
>> unsigned int lane = 0;
>> - struct resource res;
>> int err;
>>
>> - if (of_pci_range_parser_init(&parser, np)) {
>> - dev_err(dev, "missing \"ranges\" property\n");
>> - return -EINVAL;
>> - }
>> -
>> - for_each_of_pci_range(&parser, &range) {
>> - err = of_pci_range_to_resource(&range, np, &res);
>> - if (err < 0)
>> - return err;
>> -
>> - switch (res.flags & IORESOURCE_TYPE_BITS) {
>> - case IORESOURCE_IO:
>> - /* Track the bus -> CPU I/O mapping offset. */
>> - pcie->offset.io = res.start - range.pci_addr;
>> -
>> - memcpy(&pcie->pio, &res, sizeof(res));
>> - pcie->pio.name = np->full_name;
>> -
>> - /*
>> - * The Tegra PCIe host bridge uses this to program the
>> - * mapping of the I/O space to the physical address,
>> - * so we override the .start and .end fields here that
>> - * of_pci_range_to_resource() converted to I/O space.
>> - * We also set the IORESOURCE_MEM type to clarify that
>> - * the resource is in the physical memory space.
>> - */
>> - pcie->io.start = range.cpu_addr;
>> - pcie->io.end = range.cpu_addr + range.size - 1;
>> - pcie->io.flags = IORESOURCE_MEM;
>> - pcie->io.name = "I/O";
>> -
>> - memcpy(&res, &pcie->io, sizeof(res));
>> - break;
>> -
>> - case IORESOURCE_MEM:
>> - /*
>> - * Track the bus -> CPU memory mapping offset. This
>> - * assumes that the prefetchable and non-prefetchable
>> - * regions will be the last of type IORESOURCE_MEM in
>> - * the ranges property.
>> - * */
>> - pcie->offset.mem = res.start - range.pci_addr;
>> -
>> - if (res.flags & IORESOURCE_PREFETCH) {
>> - memcpy(&pcie->prefetch, &res, sizeof(res));
>> - pcie->prefetch.name = "prefetchable";
>> - } else {
>> - memcpy(&pcie->mem, &res, sizeof(res));
>> - pcie->mem.name = "non-prefetchable";
>> - }
>> - break;
>> - }
>> - }
>> -
>> - err = of_pci_parse_bus_range(np, &pcie->busn);
>> - if (err < 0) {
>> - dev_err(dev, "failed to parse ranges property: %d\n", err);
>> - pcie->busn.name = np->name;
>> - pcie->busn.start = 0;
>> - pcie->busn.end = 0xff;
>> - pcie->busn.flags = IORESOURCE_BUS;
>> - }
>> -
>> /* parse root ports */
>> for_each_child_of_node(np, port) {
>> struct tegra_pcie_port *rp;
>> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> struct pci_host_bridge *host;
>> struct tegra_pcie *pcie;
>> struct pci_bus *child;
>> + struct resource *bus;
>> int err;
>>
>> host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> INIT_LIST_HEAD(&pcie->ports);
>> pcie->dev = dev;
>>
>> + err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
>> + if (err) {
>> + dev_err(dev, "Getting bridge resources failed\n");
>> + return err;
>> + }
>> +
>> err = tegra_pcie_parse_dt(pcie);
>> if (err < 0)
>> return err;
>> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> goto teardown_msi;
>> }
>>
>> - err = tegra_pcie_request_resources(pcie);
>> - if (err)
>> - goto pm_runtime_put;
>> -
>> - host->busnr = pcie->busn.start;
>> + host->busnr = bus->start;
>> host->dev.parent = &pdev->dev;
>> host->ops = &tegra_pcie_ops;
>> host->map_irq = tegra_pcie_map_irq;
>> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> err = pci_scan_root_bus_bridge(host);
>> if (err < 0) {
>> dev_err(dev, "failed to register host: %d\n", err);
>> - goto free_resources;
>> + goto pm_runtime_put;
>> }
>>
>> pci_bus_size_bridges(host->bus);
>> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>
>> return 0;
>>
>> -free_resources:
>> - tegra_pcie_free_resources(pcie);
>> pm_runtime_put:
>> pm_runtime_put_sync(pcie->dev);
>> pm_runtime_disable(pcie->dev);
>> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>>
>> pci_stop_root_bus(host->bus);
>> pci_remove_root_bus(host->bus);
>> - tegra_pcie_free_resources(pcie);
>> pm_runtime_put_sync(pcie->dev);
>> pm_runtime_disable(pcie->dev);
>>
>> --
>> 2.20.1
>>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-22 17:36 ` Vidya Sagar
0 siblings, 0 replies; 13+ messages in thread
From: Vidya Sagar @ 2020-02-22 17:36 UTC (permalink / raw)
To: Lorenzo Pieralisi, Rob Herring
Cc: linux-pci, Thierry Reding, Andrew Murray, Bjorn Helgaas,
Jonathan Hunter, linux-tegra
On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> External email: Use caution opening links or attachments
>
>
> On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
>> Convert Tegra PCI host driver to use the common
>> pci_parse_request_of_pci_ranges().
>>
>> This allows removing the DT ranges parsing, PCI resource handling, and
>> private storage of resources from the driver.
>>
>> Cc: Thierry Reding <thierry.reding@gmail.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Andrew Murray <andrew.murray@arm.com>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: Jonathan Hunter <jonathanh@nvidia.com>
>> Cc: linux-tegra@vger.kernel.org
>> Signed-off-by: Rob Herring <robh@kernel.org>
>> ---
>> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
>> dependent on my prior series, specifically this patch[1].
>>
>> Compile tested only.
>>
>> Rob
>>
>> [1] https://patchwork.ozlabs.org/patch/1185555/
>>
>> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>> 1 file changed, 46 insertions(+), 141 deletions(-)
>
> Patch still applies, I need testing and ACK from Tegra maintainers
> please.
I tested this patch on Jetson-TX1 with NVMe drive connected to it.
Verified basic enumeration and functionality of the drive.
Tested-by: Vidya Sagar <vidyas@nvidia.com>
Thanks,
Vidya Sagar
>
> Thanks,
> Lorenzo
>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 673a1725ef38..83d8209a372a 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -355,16 +355,6 @@ struct tegra_pcie {
>> int irq;
>>
>> struct resource cs;
>> - struct resource io;
>> - struct resource pio;
>> - struct resource mem;
>> - struct resource prefetch;
>> - struct resource busn;
>> -
>> - struct {
>> - resource_size_t mem;
>> - resource_size_t io;
>> - } offset;
>>
>> struct clk *pex_clk;
>> struct clk *afi_clk;
>> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>>
>> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
>> -{
>> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> - struct list_head *windows = &host->windows;
>> - struct device *dev = pcie->dev;
>> - int err;
>> -
>> - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
>> - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
>> - pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
>> - pci_add_resource(windows, &pcie->busn);
>> -
>> - err = devm_request_pci_bus_resources(dev, windows);
>> - if (err < 0) {
>> - pci_free_resource_list(windows);
>> - return err;
>> - }
>> -
>> - pci_remap_iospace(&pcie->pio, pcie->io.start);
>> -
>> - return 0;
>> -}
>> -
>> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
>> -{
>> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> - struct list_head *windows = &host->windows;
>> -
>> - pci_unmap_iospace(&pcie->pio);
>> - pci_free_resource_list(windows);
>> -}
>> -
>> static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>> {
>> struct tegra_pcie *pcie = pdev->bus->sysdata;
>> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>> */
>> static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>> {
>> - u32 fpci_bar, size, axi_address;
>> + u32 size;
>> + struct resource_entry *entry;
>> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>>
>> /* Bar 0: type 1 extended configuration space */
>> size = resource_size(&pcie->cs);
>> afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>> afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>>
>> - /* Bar 1: downstream IO bar */
>> - fpci_bar = 0xfdfc0000;
>> - size = resource_size(&pcie->io);
>> - axi_address = pcie->io.start;
>> - afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> - afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> -
>> - /* Bar 2: prefetchable memory BAR */
>> - fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> - size = resource_size(&pcie->prefetch);
>> - axi_address = pcie->prefetch.start;
>> - afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> - afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> -
>> - /* Bar 3: non prefetchable memory BAR */
>> - fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> - size = resource_size(&pcie->mem);
>> - axi_address = pcie->mem.start;
>> - afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> - afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> + resource_list_for_each_entry(entry, &bridge->windows) {
>> + u32 fpci_bar, axi_address;
>> + struct resource *res = entry->res;
>> +
>> + size = resource_size(res);
>> +
>> + switch (resource_type(res)) {
>> + case IORESOURCE_IO:
>> + /* Bar 1: downstream IO bar */
>> + fpci_bar = 0xfdfc0000;
>> + axi_address = pci_pio_to_address(res->start);
>> + afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> + afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> + break;
>> + case IORESOURCE_MEM:
>> + fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
>> + axi_address = res->start;
>> +
>> + if (res->flags & IORESOURCE_PREFETCH) {
>> + /* Bar 2: prefetchable memory BAR */
>> + afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> + afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> +
>> + } else {
>> + /* Bar 3: non prefetchable memory BAR */
>> + afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> + afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> + }
>> + break;
>> + }
>> + }
>>
>> /* NULL out the remaining BARs as they are not used */
>> afi_writel(pcie, 0, AFI_AXI_BAR4_START);
>> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>> struct device *dev = pcie->dev;
>> struct device_node *np = dev->of_node, *port;
>> const struct tegra_pcie_soc *soc = pcie->soc;
>> - struct of_pci_range_parser parser;
>> - struct of_pci_range range;
>> u32 lanes = 0, mask = 0;
>> unsigned int lane = 0;
>> - struct resource res;
>> int err;
>>
>> - if (of_pci_range_parser_init(&parser, np)) {
>> - dev_err(dev, "missing \"ranges\" property\n");
>> - return -EINVAL;
>> - }
>> -
>> - for_each_of_pci_range(&parser, &range) {
>> - err = of_pci_range_to_resource(&range, np, &res);
>> - if (err < 0)
>> - return err;
>> -
>> - switch (res.flags & IORESOURCE_TYPE_BITS) {
>> - case IORESOURCE_IO:
>> - /* Track the bus -> CPU I/O mapping offset. */
>> - pcie->offset.io = res.start - range.pci_addr;
>> -
>> - memcpy(&pcie->pio, &res, sizeof(res));
>> - pcie->pio.name = np->full_name;
>> -
>> - /*
>> - * The Tegra PCIe host bridge uses this to program the
>> - * mapping of the I/O space to the physical address,
>> - * so we override the .start and .end fields here that
>> - * of_pci_range_to_resource() converted to I/O space.
>> - * We also set the IORESOURCE_MEM type to clarify that
>> - * the resource is in the physical memory space.
>> - */
>> - pcie->io.start = range.cpu_addr;
>> - pcie->io.end = range.cpu_addr + range.size - 1;
>> - pcie->io.flags = IORESOURCE_MEM;
>> - pcie->io.name = "I/O";
>> -
>> - memcpy(&res, &pcie->io, sizeof(res));
>> - break;
>> -
>> - case IORESOURCE_MEM:
>> - /*
>> - * Track the bus -> CPU memory mapping offset. This
>> - * assumes that the prefetchable and non-prefetchable
>> - * regions will be the last of type IORESOURCE_MEM in
>> - * the ranges property.
>> - * */
>> - pcie->offset.mem = res.start - range.pci_addr;
>> -
>> - if (res.flags & IORESOURCE_PREFETCH) {
>> - memcpy(&pcie->prefetch, &res, sizeof(res));
>> - pcie->prefetch.name = "prefetchable";
>> - } else {
>> - memcpy(&pcie->mem, &res, sizeof(res));
>> - pcie->mem.name = "non-prefetchable";
>> - }
>> - break;
>> - }
>> - }
>> -
>> - err = of_pci_parse_bus_range(np, &pcie->busn);
>> - if (err < 0) {
>> - dev_err(dev, "failed to parse ranges property: %d\n", err);
>> - pcie->busn.name = np->name;
>> - pcie->busn.start = 0;
>> - pcie->busn.end = 0xff;
>> - pcie->busn.flags = IORESOURCE_BUS;
>> - }
>> -
>> /* parse root ports */
>> for_each_child_of_node(np, port) {
>> struct tegra_pcie_port *rp;
>> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> struct pci_host_bridge *host;
>> struct tegra_pcie *pcie;
>> struct pci_bus *child;
>> + struct resource *bus;
>> int err;
>>
>> host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> INIT_LIST_HEAD(&pcie->ports);
>> pcie->dev = dev;
>>
>> + err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
>> + if (err) {
>> + dev_err(dev, "Getting bridge resources failed\n");
>> + return err;
>> + }
>> +
>> err = tegra_pcie_parse_dt(pcie);
>> if (err < 0)
>> return err;
>> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> goto teardown_msi;
>> }
>>
>> - err = tegra_pcie_request_resources(pcie);
>> - if (err)
>> - goto pm_runtime_put;
>> -
>> - host->busnr = pcie->busn.start;
>> + host->busnr = bus->start;
>> host->dev.parent = &pdev->dev;
>> host->ops = &tegra_pcie_ops;
>> host->map_irq = tegra_pcie_map_irq;
>> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>> err = pci_scan_root_bus_bridge(host);
>> if (err < 0) {
>> dev_err(dev, "failed to register host: %d\n", err);
>> - goto free_resources;
>> + goto pm_runtime_put;
>> }
>>
>> pci_bus_size_bridges(host->bus);
>> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>
>> return 0;
>>
>> -free_resources:
>> - tegra_pcie_free_resources(pcie);
>> pm_runtime_put:
>> pm_runtime_put_sync(pcie->dev);
>> pm_runtime_disable(pcie->dev);
>> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>>
>> pci_stop_root_bus(host->bus);
>> pci_remove_root_bus(host->bus);
>> - tegra_pcie_free_resources(pcie);
>> pm_runtime_put_sync(pcie->dev);
>> pm_runtime_disable(pcie->dev);
>>
>> --
>> 2.20.1
>>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
2020-02-22 17:36 ` Vidya Sagar
@ 2020-02-24 11:37 ` Lorenzo Pieralisi
-1 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 11:37 UTC (permalink / raw)
To: Vidya Sagar
Cc: Rob Herring, linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding,
Andrew Murray, Bjorn Helgaas, Jonathan Hunter,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
On Sat, Feb 22, 2020 at 11:06:18PM +0530, Vidya Sagar wrote:
>
>
> On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> > External email: Use caution opening links or attachments
> >
> >
> > On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> > > Convert Tegra PCI host driver to use the common
> > > pci_parse_request_of_pci_ranges().
> > >
> > > This allows removing the DT ranges parsing, PCI resource handling, and
> > > private storage of resources from the driver.
> > >
> > > Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > > Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> > > Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> > > Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> > > Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > > Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > ---
> > > Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> > > dependent on my prior series, specifically this patch[1].
> > >
> > > Compile tested only.
> > >
> > > Rob
> > >
> > > [1] https://patchwork.ozlabs.org/patch/1185555/
> > >
> > > drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> > > 1 file changed, 46 insertions(+), 141 deletions(-)
> >
> > Patch still applies, I need testing and ACK from Tegra maintainers
> > please.
> I tested this patch on Jetson-TX1 with NVMe drive connected to it.
> Verified basic enumeration and functionality of the drive.
>
> Tested-by: Vidya Sagar <vidyas-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Thanks a lot, I need Thierry's ACK to merge it, thanks.
Lorenzo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-24 11:37 ` Lorenzo Pieralisi
0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 11:37 UTC (permalink / raw)
To: Vidya Sagar
Cc: Rob Herring, linux-pci, Thierry Reding, Andrew Murray,
Bjorn Helgaas, Jonathan Hunter, linux-tegra
On Sat, Feb 22, 2020 at 11:06:18PM +0530, Vidya Sagar wrote:
>
>
> On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> > External email: Use caution opening links or attachments
> >
> >
> > On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> > > Convert Tegra PCI host driver to use the common
> > > pci_parse_request_of_pci_ranges().
> > >
> > > This allows removing the DT ranges parsing, PCI resource handling, and
> > > private storage of resources from the driver.
> > >
> > > Cc: Thierry Reding <thierry.reding@gmail.com>
> > > Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > > Cc: Andrew Murray <andrew.murray@arm.com>
> > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > Cc: Jonathan Hunter <jonathanh@nvidia.com>
> > > Cc: linux-tegra@vger.kernel.org
> > > Signed-off-by: Rob Herring <robh@kernel.org>
> > > ---
> > > Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> > > dependent on my prior series, specifically this patch[1].
> > >
> > > Compile tested only.
> > >
> > > Rob
> > >
> > > [1] https://patchwork.ozlabs.org/patch/1185555/
> > >
> > > drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> > > 1 file changed, 46 insertions(+), 141 deletions(-)
> >
> > Patch still applies, I need testing and ACK from Tegra maintainers
> > please.
> I tested this patch on Jetson-TX1 with NVMe drive connected to it.
> Verified basic enumeration and functionality of the drive.
>
> Tested-by: Vidya Sagar <vidyas@nvidia.com>
Thanks a lot, I need Thierry's ACK to merge it, thanks.
Lorenzo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2020-02-24 13:17 ` Thierry Reding
[not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
1 sibling, 0 replies; 13+ messages in thread
From: Thierry Reding @ 2020-02-24 13:17 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Lorenzo Pieralisi,
Andrew Murray, Bjorn Helgaas, Jonathan Hunter,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 1233 bytes --]
On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
>
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
>
> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
>
> Compile tested only.
>
> Rob
>
> [1] https://patchwork.ozlabs.org/patch/1185555/
>
> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> 1 file changed, 46 insertions(+), 141 deletions(-)
Acked-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-24 13:17 ` Thierry Reding
0 siblings, 0 replies; 13+ messages in thread
From: Thierry Reding @ 2020-02-24 13:17 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci, Lorenzo Pieralisi, Andrew Murray, Bjorn Helgaas,
Jonathan Hunter, linux-tegra
[-- Attachment #1: Type: text/plain, Size: 1021 bytes --]
On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
>
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Andrew Murray <andrew.murray@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
>
> Compile tested only.
>
> Rob
>
> [1] https://patchwork.ozlabs.org/patch/1185555/
>
> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> 1 file changed, 46 insertions(+), 141 deletions(-)
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2020-02-24 13:55 ` Lorenzo Pieralisi
[not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
1 sibling, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 13:55 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding, Andrew Murray,
Bjorn Helgaas, Jonathan Hunter,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
>
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
>
> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
>
> Compile tested only.
>
> Rob
>
> [1] https://patchwork.ozlabs.org/patch/1185555/
>
> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> 1 file changed, 46 insertions(+), 141 deletions(-)
Applied to pci/tegra for v5.7, thanks.
Lorenzo
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
> int irq;
>
> struct resource cs;
> - struct resource io;
> - struct resource pio;
> - struct resource mem;
> - struct resource prefetch;
> - struct resource busn;
> -
> - struct {
> - resource_size_t mem;
> - resource_size_t io;
> - } offset;
>
> struct clk *pex_clk;
> struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> - struct device *dev = pcie->dev;
> - int err;
> -
> - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> - pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> - pci_add_resource(windows, &pcie->busn);
> -
> - err = devm_request_pci_bus_resources(dev, windows);
> - if (err < 0) {
> - pci_free_resource_list(windows);
> - return err;
> - }
> -
> - pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> - return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> -
> - pci_unmap_iospace(&pcie->pio);
> - pci_free_resource_list(windows);
> -}
> -
> static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
> {
> struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
> */
> static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
> {
> - u32 fpci_bar, size, axi_address;
> + u32 size;
> + struct resource_entry *entry;
> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>
> /* Bar 0: type 1 extended configuration space */
> size = resource_size(&pcie->cs);
> afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
> afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>
> - /* Bar 1: downstream IO bar */
> - fpci_bar = 0xfdfc0000;
> - size = resource_size(&pcie->io);
> - axi_address = pcie->io.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> - /* Bar 2: prefetchable memory BAR */
> - fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->prefetch);
> - axi_address = pcie->prefetch.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> - /* Bar 3: non prefetchable memory BAR */
> - fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->mem);
> - axi_address = pcie->mem.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + resource_list_for_each_entry(entry, &bridge->windows) {
> + u32 fpci_bar, axi_address;
> + struct resource *res = entry->res;
> +
> + size = resource_size(res);
> +
> + switch (resource_type(res)) {
> + case IORESOURCE_IO:
> + /* Bar 1: downstream IO bar */
> + fpci_bar = 0xfdfc0000;
> + axi_address = pci_pio_to_address(res->start);
> + afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> + break;
> + case IORESOURCE_MEM:
> + fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> + axi_address = res->start;
> +
> + if (res->flags & IORESOURCE_PREFETCH) {
> + /* Bar 2: prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> + } else {
> + /* Bar 3: non prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + }
> + break;
> + }
> + }
>
> /* NULL out the remaining BARs as they are not used */
> afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
> struct device *dev = pcie->dev;
> struct device_node *np = dev->of_node, *port;
> const struct tegra_pcie_soc *soc = pcie->soc;
> - struct of_pci_range_parser parser;
> - struct of_pci_range range;
> u32 lanes = 0, mask = 0;
> unsigned int lane = 0;
> - struct resource res;
> int err;
>
> - if (of_pci_range_parser_init(&parser, np)) {
> - dev_err(dev, "missing \"ranges\" property\n");
> - return -EINVAL;
> - }
> -
> - for_each_of_pci_range(&parser, &range) {
> - err = of_pci_range_to_resource(&range, np, &res);
> - if (err < 0)
> - return err;
> -
> - switch (res.flags & IORESOURCE_TYPE_BITS) {
> - case IORESOURCE_IO:
> - /* Track the bus -> CPU I/O mapping offset. */
> - pcie->offset.io = res.start - range.pci_addr;
> -
> - memcpy(&pcie->pio, &res, sizeof(res));
> - pcie->pio.name = np->full_name;
> -
> - /*
> - * The Tegra PCIe host bridge uses this to program the
> - * mapping of the I/O space to the physical address,
> - * so we override the .start and .end fields here that
> - * of_pci_range_to_resource() converted to I/O space.
> - * We also set the IORESOURCE_MEM type to clarify that
> - * the resource is in the physical memory space.
> - */
> - pcie->io.start = range.cpu_addr;
> - pcie->io.end = range.cpu_addr + range.size - 1;
> - pcie->io.flags = IORESOURCE_MEM;
> - pcie->io.name = "I/O";
> -
> - memcpy(&res, &pcie->io, sizeof(res));
> - break;
> -
> - case IORESOURCE_MEM:
> - /*
> - * Track the bus -> CPU memory mapping offset. This
> - * assumes that the prefetchable and non-prefetchable
> - * regions will be the last of type IORESOURCE_MEM in
> - * the ranges property.
> - * */
> - pcie->offset.mem = res.start - range.pci_addr;
> -
> - if (res.flags & IORESOURCE_PREFETCH) {
> - memcpy(&pcie->prefetch, &res, sizeof(res));
> - pcie->prefetch.name = "prefetchable";
> - } else {
> - memcpy(&pcie->mem, &res, sizeof(res));
> - pcie->mem.name = "non-prefetchable";
> - }
> - break;
> - }
> - }
> -
> - err = of_pci_parse_bus_range(np, &pcie->busn);
> - if (err < 0) {
> - dev_err(dev, "failed to parse ranges property: %d\n", err);
> - pcie->busn.name = np->name;
> - pcie->busn.start = 0;
> - pcie->busn.end = 0xff;
> - pcie->busn.flags = IORESOURCE_BUS;
> - }
> -
> /* parse root ports */
> for_each_child_of_node(np, port) {
> struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> struct pci_host_bridge *host;
> struct tegra_pcie *pcie;
> struct pci_bus *child;
> + struct resource *bus;
> int err;
>
> host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> INIT_LIST_HEAD(&pcie->ports);
> pcie->dev = dev;
>
> + err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> + if (err) {
> + dev_err(dev, "Getting bridge resources failed\n");
> + return err;
> + }
> +
> err = tegra_pcie_parse_dt(pcie);
> if (err < 0)
> return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> goto teardown_msi;
> }
>
> - err = tegra_pcie_request_resources(pcie);
> - if (err)
> - goto pm_runtime_put;
> -
> - host->busnr = pcie->busn.start;
> + host->busnr = bus->start;
> host->dev.parent = &pdev->dev;
> host->ops = &tegra_pcie_ops;
> host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> err = pci_scan_root_bus_bridge(host);
> if (err < 0) {
> dev_err(dev, "failed to register host: %d\n", err);
> - goto free_resources;
> + goto pm_runtime_put;
> }
>
> pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>
> return 0;
>
> -free_resources:
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put:
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>
> pci_stop_root_bus(host->bus);
> pci_remove_root_bus(host->bus);
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-24 13:55 ` Lorenzo Pieralisi
0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 13:55 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci, Thierry Reding, Andrew Murray, Bjorn Helgaas,
Jonathan Hunter, linux-tegra
On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
>
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Andrew Murray <andrew.murray@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
>
> Compile tested only.
>
> Rob
>
> [1] https://patchwork.ozlabs.org/patch/1185555/
>
> drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> 1 file changed, 46 insertions(+), 141 deletions(-)
Applied to pci/tegra for v5.7, thanks.
Lorenzo
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
> int irq;
>
> struct resource cs;
> - struct resource io;
> - struct resource pio;
> - struct resource mem;
> - struct resource prefetch;
> - struct resource busn;
> -
> - struct {
> - resource_size_t mem;
> - resource_size_t io;
> - } offset;
>
> struct clk *pex_clk;
> struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> - struct device *dev = pcie->dev;
> - int err;
> -
> - pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> - pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> - pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> - pci_add_resource(windows, &pcie->busn);
> -
> - err = devm_request_pci_bus_resources(dev, windows);
> - if (err < 0) {
> - pci_free_resource_list(windows);
> - return err;
> - }
> -
> - pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> - return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> - struct list_head *windows = &host->windows;
> -
> - pci_unmap_iospace(&pcie->pio);
> - pci_free_resource_list(windows);
> -}
> -
> static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
> {
> struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
> */
> static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
> {
> - u32 fpci_bar, size, axi_address;
> + u32 size;
> + struct resource_entry *entry;
> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>
> /* Bar 0: type 1 extended configuration space */
> size = resource_size(&pcie->cs);
> afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
> afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>
> - /* Bar 1: downstream IO bar */
> - fpci_bar = 0xfdfc0000;
> - size = resource_size(&pcie->io);
> - axi_address = pcie->io.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> - /* Bar 2: prefetchable memory BAR */
> - fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->prefetch);
> - axi_address = pcie->prefetch.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> - /* Bar 3: non prefetchable memory BAR */
> - fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> - size = resource_size(&pcie->mem);
> - axi_address = pcie->mem.start;
> - afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> - afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> - afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + resource_list_for_each_entry(entry, &bridge->windows) {
> + u32 fpci_bar, axi_address;
> + struct resource *res = entry->res;
> +
> + size = resource_size(res);
> +
> + switch (resource_type(res)) {
> + case IORESOURCE_IO:
> + /* Bar 1: downstream IO bar */
> + fpci_bar = 0xfdfc0000;
> + axi_address = pci_pio_to_address(res->start);
> + afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> + break;
> + case IORESOURCE_MEM:
> + fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> + axi_address = res->start;
> +
> + if (res->flags & IORESOURCE_PREFETCH) {
> + /* Bar 2: prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> + } else {
> + /* Bar 3: non prefetchable memory BAR */
> + afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> + afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> + afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> + }
> + break;
> + }
> + }
>
> /* NULL out the remaining BARs as they are not used */
> afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
> struct device *dev = pcie->dev;
> struct device_node *np = dev->of_node, *port;
> const struct tegra_pcie_soc *soc = pcie->soc;
> - struct of_pci_range_parser parser;
> - struct of_pci_range range;
> u32 lanes = 0, mask = 0;
> unsigned int lane = 0;
> - struct resource res;
> int err;
>
> - if (of_pci_range_parser_init(&parser, np)) {
> - dev_err(dev, "missing \"ranges\" property\n");
> - return -EINVAL;
> - }
> -
> - for_each_of_pci_range(&parser, &range) {
> - err = of_pci_range_to_resource(&range, np, &res);
> - if (err < 0)
> - return err;
> -
> - switch (res.flags & IORESOURCE_TYPE_BITS) {
> - case IORESOURCE_IO:
> - /* Track the bus -> CPU I/O mapping offset. */
> - pcie->offset.io = res.start - range.pci_addr;
> -
> - memcpy(&pcie->pio, &res, sizeof(res));
> - pcie->pio.name = np->full_name;
> -
> - /*
> - * The Tegra PCIe host bridge uses this to program the
> - * mapping of the I/O space to the physical address,
> - * so we override the .start and .end fields here that
> - * of_pci_range_to_resource() converted to I/O space.
> - * We also set the IORESOURCE_MEM type to clarify that
> - * the resource is in the physical memory space.
> - */
> - pcie->io.start = range.cpu_addr;
> - pcie->io.end = range.cpu_addr + range.size - 1;
> - pcie->io.flags = IORESOURCE_MEM;
> - pcie->io.name = "I/O";
> -
> - memcpy(&res, &pcie->io, sizeof(res));
> - break;
> -
> - case IORESOURCE_MEM:
> - /*
> - * Track the bus -> CPU memory mapping offset. This
> - * assumes that the prefetchable and non-prefetchable
> - * regions will be the last of type IORESOURCE_MEM in
> - * the ranges property.
> - * */
> - pcie->offset.mem = res.start - range.pci_addr;
> -
> - if (res.flags & IORESOURCE_PREFETCH) {
> - memcpy(&pcie->prefetch, &res, sizeof(res));
> - pcie->prefetch.name = "prefetchable";
> - } else {
> - memcpy(&pcie->mem, &res, sizeof(res));
> - pcie->mem.name = "non-prefetchable";
> - }
> - break;
> - }
> - }
> -
> - err = of_pci_parse_bus_range(np, &pcie->busn);
> - if (err < 0) {
> - dev_err(dev, "failed to parse ranges property: %d\n", err);
> - pcie->busn.name = np->name;
> - pcie->busn.start = 0;
> - pcie->busn.end = 0xff;
> - pcie->busn.flags = IORESOURCE_BUS;
> - }
> -
> /* parse root ports */
> for_each_child_of_node(np, port) {
> struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> struct pci_host_bridge *host;
> struct tegra_pcie *pcie;
> struct pci_bus *child;
> + struct resource *bus;
> int err;
>
> host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> INIT_LIST_HEAD(&pcie->ports);
> pcie->dev = dev;
>
> + err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> + if (err) {
> + dev_err(dev, "Getting bridge resources failed\n");
> + return err;
> + }
> +
> err = tegra_pcie_parse_dt(pcie);
> if (err < 0)
> return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> goto teardown_msi;
> }
>
> - err = tegra_pcie_request_resources(pcie);
> - if (err)
> - goto pm_runtime_put;
> -
> - host->busnr = pcie->busn.start;
> + host->busnr = bus->start;
> host->dev.parent = &pdev->dev;
> host->ops = &tegra_pcie_ops;
> host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
> err = pci_scan_root_bus_bridge(host);
> if (err < 0) {
> dev_err(dev, "failed to register host: %d\n", err);
> - goto free_resources;
> + goto pm_runtime_put;
> }
>
> pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>
> return 0;
>
> -free_resources:
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put:
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>
> pci_stop_root_bus(host->bus);
> pci_remove_root_bus(host->bus);
> - tegra_pcie_free_resources(pcie);
> pm_runtime_put_sync(pcie->dev);
> pm_runtime_disable(pcie->dev);
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2020-02-24 13:55 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
2019-10-30 14:51 ` kbuild test robot
2019-10-30 14:51 ` kbuild test robot
[not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2020-02-21 14:20 ` Lorenzo Pieralisi
2020-02-21 14:20 ` Lorenzo Pieralisi
[not found] ` <20200221142051.GB15440-LhTu/34fCX3ZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2020-02-22 17:36 ` Vidya Sagar
2020-02-22 17:36 ` Vidya Sagar
[not found] ` <c7392952-929a-5be4-ab06-9cf04810290f-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2020-02-24 11:37 ` Lorenzo Pieralisi
2020-02-24 11:37 ` Lorenzo Pieralisi
2020-02-24 13:17 ` Thierry Reding
2020-02-24 13:17 ` Thierry Reding
2020-02-24 13:55 ` Lorenzo Pieralisi
2020-02-24 13:55 ` Lorenzo Pieralisi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.