2015-11-02 16:38:40

by Phil Edworthy

[permalink] [raw]
Subject: [PATCH 0/3] Fix rcar-pcie for arm64

The first patches fixes the build problem, and the second patch reverts the
patch that removed the driver from arm64 builds. The final patch add a compat
string for the r8a7795 (arm64) device.

Tested on arm Koelsch board, all ok.

Tested on arm64 Salvator-X board using renesas-drivers-2015-10-27-v4.3-rc7 from
git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git with PCI
next merged.
Apart from patches to add the PCIe clock and DT nodes, I had to revert these
patches to get it to work on arm64:
f075915ac0b1 ("PCI/MSI: Drop domain field from msi_controller")
d8a1cb757550 ("PCI/MSI: Let pci_msi_get_domain use struct device::msi_domain")
I'll look into this, but it doesn't stop us from applying these patches.

Harunobu Kurokawa (1):
PCI: pcie-rcar: Add support for R-Car H3.

Phil Edworthy (2):
PCI: pcie-rcar: Convert to DT resource parsing API
Revert "PCI: rcar: Build pcie-rcar.c only on ARM"

Documentation/devicetree/bindings/pci/rcar-pci.txt | 3 +-
drivers/pci/host/Kconfig | 3 +-
drivers/pci/host/pcie-rcar.c | 118 +++++++++++++--------
3 files changed, 78 insertions(+), 46 deletions(-)

--
1.9.1


2015-11-02 16:39:07

by Phil Edworthy

[permalink] [raw]
Subject: [PATCH 1/3] PCI: pcie-rcar: Convert to DT resource parsing API

The main purpose of this change is to avoid calling pci_ioremap_io() as
this is not available on arm64. However, instead of doing the range passing
in this driver we can utilise of_pci_get_host_bridge_resources().

This is similar to changes made to the generic PCI host driver in commit
dbf9826d "PCI: generic: Convert to DT resource parsing API".

Signed-off-by: Phil Edworthy <[email protected]>
---
drivers/pci/host/pcie-rcar.c | 117 +++++++++++++++++++++++++++----------------
1 file changed, 74 insertions(+), 43 deletions(-)

diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index f4fa6c5..27c0521 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -108,8 +108,6 @@
#define RCAR_PCI_MAX_RESOURCES 4
#define MAX_NR_INBOUND_MAPS 6

-static unsigned long global_io_offset;
-
struct rcar_msi {
DECLARE_BITMAP(used, INT_PCI_MSI_NR);
struct irq_domain *domain;
@@ -138,8 +136,7 @@ struct rcar_pcie {
#endif
struct device *dev;
void __iomem *base;
- struct resource res[RCAR_PCI_MAX_RESOURCES];
- struct resource busn;
+ struct list_head resources;
int root_bus_nr;
struct clk *clk;
struct clk *bus_clk;
@@ -323,10 +320,9 @@ static struct pci_ops rcar_pcie_ops = {
.write = rcar_pcie_write_conf,
};

-static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
+static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie,
+ struct resource *res)
{
- struct resource *res = &pcie->res[win];
-
/* Setup PCIe address space mappings for each resource */
resource_size_t size;
resource_size_t res_start;
@@ -359,31 +355,33 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
}

-static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pcie)
+static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci)
{
- struct resource *res;
- int i;
-
- pcie->root_bus_nr = pcie->busn.start;
+ struct resource_entry *win;
+ int i = 0;

/* Setup PCI resources */
- for (i = 0; i < RCAR_PCI_MAX_RESOURCES; i++) {
+ resource_list_for_each_entry(win, &pci->resources) {
+ struct resource *res = win->res;

- res = &pcie->res[i];
if (!res->flags)
continue;

- rcar_pcie_setup_window(i, pcie);
-
- if (res->flags & IORESOURCE_IO) {
- phys_addr_t io_start = pci_pio_to_address(res->start);
- pci_ioremap_io(global_io_offset, io_start);
- global_io_offset += SZ_64K;
+ switch (resource_type(res)) {
+ case IORESOURCE_IO:
+ case IORESOURCE_MEM:
+ rcar_pcie_setup_window(i, pci, res);
+ i++;
+ break;
+ case IORESOURCE_BUS:
+ pci->root_bus_nr = res->start;
+ break;
+ default:
+ continue;
}

pci_add_resource(resource, res);
}
- pci_add_resource(resource, &pcie->busn);

return 1;
}
@@ -923,14 +921,64 @@ static const struct of_device_id rcar_pcie_of_match[] = {
};
MODULE_DEVICE_TABLE(of, rcar_pcie_of_match);

+static void rcar_pcie_release_of_pci_ranges(struct rcar_pcie *pci)
+{
+ pci_free_resource_list(&pci->resources);
+}
+
+static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
+{
+ int err, res_valid = 0;
+ struct device *dev = pci->dev;
+ struct device_node *np = dev->of_node;
+ resource_size_t iobase;
+ struct resource_entry *win;
+
+ err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase);
+ if (err)
+ return err;
+
+ resource_list_for_each_entry(win, &pci->resources) {
+ struct resource *parent, *res = win->res;
+
+ switch (resource_type(res)) {
+ case IORESOURCE_IO:
+ parent = &ioport_resource;
+ err = pci_remap_iospace(res, iobase);
+ if (err) {
+ dev_warn(dev, "error %d: failed to map resource %pR\n",
+ err, res);
+ continue;
+ }
+ break;
+ case IORESOURCE_MEM:
+ parent = &iomem_resource;
+ res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+ break;
+
+ case IORESOURCE_BUS:
+ default:
+ continue;
+ }
+
+ err = devm_request_resource(dev, parent, res);
+ if (err)
+ goto out_release_res;
+ }
+
+ return 0;
+
+out_release_res:
+ rcar_pcie_release_of_pci_ranges(pci);
+ return err;
+}
+
static int rcar_pcie_probe(struct platform_device *pdev)
{
struct rcar_pcie *pcie;
unsigned int data;
- struct of_pci_range range;
- struct of_pci_range_parser parser;
const struct of_device_id *of_id;
- int err, win = 0;
+ int err;
int (*hw_init_fn)(struct rcar_pcie *);

pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
@@ -940,16 +988,9 @@ static int rcar_pcie_probe(struct platform_device *pdev)
pcie->dev = &pdev->dev;
platform_set_drvdata(pdev, pcie);

- /* Get the bus range */
- if (of_pci_parse_bus_range(pdev->dev.of_node, &pcie->busn)) {
- dev_err(&pdev->dev, "failed to parse bus-range property\n");
- return -EINVAL;
- }
+ INIT_LIST_HEAD(&pcie->resources);

- if (of_pci_range_parser_init(&parser, pdev->dev.of_node)) {
- dev_err(&pdev->dev, "missing ranges property\n");
- return -EINVAL;
- }
+ rcar_pcie_parse_request_of_pci_ranges(pcie);

err = rcar_pcie_get_resources(pdev, pcie);
if (err < 0) {
@@ -957,16 +998,6 @@ static int rcar_pcie_probe(struct platform_device *pdev)
return err;
}

- for_each_of_pci_range(&parser, &range) {
- err = of_pci_range_to_resource(&range, pdev->dev.of_node,
- &pcie->res[win++]);
- if (err < 0)
- return err;
-
- if (win > RCAR_PCI_MAX_RESOURCES)
- break;
- }
-
err = rcar_pcie_parse_map_dma_ranges(pcie, pdev->dev.of_node);
if (err)
return err;
--
1.9.1

2015-11-02 16:39:20

by Phil Edworthy

[permalink] [raw]
Subject: [PATCH 2/3] Revert "PCI: rcar: Build pcie-rcar.c only on ARM"

Now that we can build on arm64, revert commit 7c537c67d2e4
("PCI: rcar: Build pcie-rcar.c only on ARM").

Signed-off-by: Phil Edworthy <[email protected]>
---
drivers/pci/host/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 2af0571..ad27664 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -48,8 +48,7 @@ config PCI_RCAR_GEN2

config PCI_RCAR_GEN2_PCIE
bool "Renesas R-Car PCIe controller"
- depends on ARM
- depends on ARCH_SHMOBILE || COMPILE_TEST
+ depends on ARCH_SHMOBILE || (ARM && COMPILE_TEST)
help
Say Y here if you want PCIe controller support on R-Car Gen2 SoCs.

--
1.9.1

2015-11-02 16:39:38

by Phil Edworthy

[permalink] [raw]
Subject: [PATCH 3/3] PCI: pcie-rcar: Add support for R-Car H3.

From: Harunobu Kurokawa <[email protected]>

R-Car H3 device is r8a7795

Signed-off-by: Harunobu Kurokawa <[email protected]>
---
Documentation/devicetree/bindings/pci/rcar-pci.txt | 3 ++-
drivers/pci/host/pcie-rcar.c | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt
index 29d3b98..ab2e75f 100644
--- a/Documentation/devicetree/bindings/pci/rcar-pci.txt
+++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt
@@ -2,7 +2,8 @@

Required properties:
- compatible: should contain one of the following
- "renesas,pcie-r8a7779", "renesas,pcie-r8a7790", "renesas,pcie-r8a7791"
+ "renesas,pcie-r8a7779", "renesas,pcie-r8a7790", "renesas,pcie-r8a7791",
+ "renesas,pcie-r8a7795"
- reg: base address and length of the pcie controller registers.
- #address-cells: set to <3>
- #size-cells: set to <2>
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 27c0521..2377bf0 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -917,6 +917,7 @@ static const struct of_device_id rcar_pcie_of_match[] = {
{ .compatible = "renesas,pcie-r8a7779", .data = rcar_pcie_hw_init_h1 },
{ .compatible = "renesas,pcie-r8a7790", .data = rcar_pcie_hw_init },
{ .compatible = "renesas,pcie-r8a7791", .data = rcar_pcie_hw_init },
+ { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init },
{},
};
MODULE_DEVICE_TABLE(of, rcar_pcie_of_match);
--
1.9.1

2015-11-02 21:33:22

by Wolfram Sang

[permalink] [raw]
Subject: Re: [PATCH 0/3] Fix rcar-pcie for arm64


> The first patches fixes the build problem, and the second patch reverts the
> patch that removed the driver from arm64 builds. The final patch add a compat
> string for the r8a7795 (arm64) device.

Thanks. I will test them next week when I have access to my board again.

> Apart from patches to add the PCIe clock and DT nodes, I had to revert these
> patches to get it to work on arm64:
> f075915ac0b1 ("PCI/MSI: Drop domain field from msi_controller")
> d8a1cb757550 ("PCI/MSI: Let pci_msi_get_domain use struct device::msi_domain")

Does that solve the MSI problems you mentioned?

Regards,

Wolfram


Attachments:
(No filename) (613.00 B)
signature.asc (819.00 B)
Download all attachments

2015-11-03 09:00:49

by Phil Edworthy

[permalink] [raw]
Subject: RE: [PATCH 0/3] Fix rcar-pcie for arm64

Hi Wolfram,

On 02 November 2015 21:33, Wolfram wrote:
> > The first patches fixes the build problem, and the second patch reverts the
> > patch that removed the driver from arm64 builds. The final patch add a compat
> > string for the r8a7795 (arm64) device.
>
> Thanks. I will test them next week when I have access to my board again.
It's worth mentioning that I had some troubles on my Salvator-X board
with some cards not being able to link up. Since my board has a socketed chip
and the board was designed for it not to be via a socket, and this is such a low
level functionality, I think this is HW related. My Intel Gigabit CT Desktop card
always works.
Also note that this PCIe controller only supports a 32-bit AXI address range,
so you need to limit memory to within the 4GiB address space. As far as I am
aware, there is no way to limit the dma mask that card drivers use via the
controller. The plan is to add support this via IOMMU.

> > Apart from patches to add the PCIe clock and DT nodes, I had to revert these
> > patches to get it to work on arm64:
> > f075915ac0b1 ("PCI/MSI: Drop domain field from msi_controller")
> > d8a1cb757550 ("PCI/MSI: Let pci_msi_get_domain use struct
> device::msi_domain")
>
> Does that solve the MSI problems you mentioned?
It avoids the problem, but I have a proper fix in the pipeline which just needs
more testing.

Thanks
Phil

2015-11-07 13:29:17

by Wolfram Sang

[permalink] [raw]
Subject: Re: [PATCH 1/3] PCI: pcie-rcar: Convert to DT resource parsing API

On Mon, Nov 02, 2015 at 04:36:13PM +0000, Phil Edworthy wrote:
> The main purpose of this change is to avoid calling pci_ioremap_io() as
> this is not available on arm64. However, instead of doing the range passing
> in this driver we can utilise of_pci_get_host_bridge_resources().
>
> This is similar to changes made to the generic PCI host driver in commit
> dbf9826d "PCI: generic: Convert to DT resource parsing API".
>
> Signed-off-by: Phil Edworthy <[email protected]>

Reported-by: Wolfram Sang <[email protected]>
Tested-by: Wolfram Sang <[email protected]>

Works for me and my USB3 card. I also like going the global io_offset
variable away and the code readability improved, too, IMO.

One question:


> + case IORESOURCE_MEM:
> + parent = &iomem_resource;
> + res_valid |= !(res->flags & IORESOURCE_PREFETCH);
> + break;

res_valid doesn't seem to be actually used?


Attachments:
(No filename) (927.00 B)
signature.asc (819.00 B)
Digital signature
Download all attachments

2015-11-07 13:30:08

by Wolfram Sang

[permalink] [raw]
Subject: Re: [PATCH 3/3] PCI: pcie-rcar: Add support for R-Car H3.

On Mon, Nov 02, 2015 at 04:36:15PM +0000, Phil Edworthy wrote:
> From: Harunobu Kurokawa <[email protected]>
>
> R-Car H3 device is r8a7795
>
> Signed-off-by: Harunobu Kurokawa <[email protected]>

Acked-by: Wolfram Sang <[email protected]>
Tested-by: Wolfram Sang <[email protected]>


Attachments:
(No filename) (348.00 B)
signature.asc (819.00 B)
Digital signature
Download all attachments

2015-11-09 09:31:28

by Phil Edworthy

[permalink] [raw]
Subject: RE: [PATCH 1/3] PCI: pcie-rcar: Convert to DT resource parsing API

Hi Wolfram,

On 07 November 2015 13:29, Wolfram wrote:
> On Mon, Nov 02, 2015 at 04:36:13PM +0000, Phil Edworthy wrote:
> > The main purpose of this change is to avoid calling pci_ioremap_io() as
> > this is not available on arm64. However, instead of doing the range passing
> > in this driver we can utilise of_pci_get_host_bridge_resources().
> >
> > This is similar to changes made to the generic PCI host driver in commit
> > dbf9826d "PCI: generic: Convert to DT resource parsing API".
> >
> > Signed-off-by: Phil Edworthy <[email protected]>
>
> Reported-by: Wolfram Sang <[email protected]>
> Tested-by: Wolfram Sang <[email protected]>
>
> Works for me and my USB3 card. I also like going the global io_offset
> variable away and the code readability improved, too, IMO.
>
> One question:
>
>
> > + case IORESOURCE_MEM:
> > + parent = &iomem_resource;
> > + res_valid |= !(res->flags & IORESOURCE_PREFETCH);
> > + break;
>
> res_valid doesn't seem to be actually used?
Ah, you are right. I'll remove this & send a v2

Thanks
Phil