From: Arnd Bergmann <arnd@arndb.de>
To: linux-arm-kernel@lists.infradead.org
Cc: Phil Edworthy <phil.edworthy@renesas.com>,
linux-pci@vger.kernel.org, linux-sh@vger.kernel.org,
Magnus Damm <magnus.damm@gmail.com>,
Valentine Barshak <valentine.barshak@cogentembedded.com>,
Simon Horman <horms@verge.net.au>,
Bjorn Helgaas <bhelgaas@google.com>,
Ben Dooks <ben.dooks@codethink.co.uk>
Subject: Re: [PATCH v4 1/9] PCI: host: rcar: Add Renesas R-Car PCIe driver
Date: Fri, 21 Mar 2014 12:04:16 +0100 [thread overview]
Message-ID: <27671657.LuGQtNBfqX@wuerfel> (raw)
In-Reply-To: <1395397968-6242-2-git-send-email-phil.edworthy@renesas.com>
On Friday 21 March 2014 10:32:40 Phil Edworthy wrote:
> +static const struct of_device_id rcar_pcie_of_match[] = {
> + { .compatible = "renesas,r8a7779-pcie", .data = (void *)RCAR_H1 },
> + { .compatible = "renesas,r8a7790-pcie", .data = (void *)RCAR_GENERIC },
> + { .compatible = "renesas,r8a7791-pcie", .data = (void *)RCAR_GENERIC },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, rcar_pcie_of_match);
The only difference between RCAR_H1 and RCAR_GENERIC seems to be the
use of the rcar_pcie_phy_init_rcar_h1 vs rcar_pcie_hw_init
functions. I think this would be expressed in a nicer way doing
static const struct of_device_id rcar_pcie_of_match[] = {
{ .compatible = "renesas,r8a7779-pcie", .data = rcar_pcie_phy_init_rcar_h1},
{ .compatible = "renesas,r8a7790-pcie", .data = rcar_pcie_hw_init},
{ .compatible = "renesas,r8a7791-pcie", .data = rcar_pcie_hw_init},
{},
};
If you need other differences in the future, you can extend this
to use a pointer to a struct containing the init function pointer.
> +static int rcar_pcie_setup_window(int win, struct resource *res,
> + struct rcar_pcie *pcie)
> +{
> + /* Setup PCIe address space mappings for each resource */
> + resource_size_t size;
> + u32 mask;
> +
> + pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
> +
> + /*
> + * The PAMR mask is calculated in units of 128Bytes, which
> + * keeps things pretty simple.
> + */
> + size = resource_size(res);
> + mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> + pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
> +
> + pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
> + pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
> +
> + /* First resource is for IO */
> + mask = PAR_ENABLE;
> + if (res->flags & IORESOURCE_IO)
> + mask |= IO_SPACE;
> +
> + pci_write_reg(pcie, mask, PCIEPTCTLR(win));
> +
> + return 0;
> +}
Would it be possible to have this done in the boot loader so the kernel
doesn't need to be bothered with it?
> +
> +static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
> +{
> + struct rcar_pcie *pcie = sys_to_pcie(sys);
> + struct resource *res;
> + int i, ret;
> +
> + pcie->root_bus_nr = sys->busnr;
> +
> + /* Setup PCI resources */
> + for (i = 0; i < PCI_MAX_RESOURCES; i++) {
> +
> + res = &pcie->res[i];
> + if (!res->flags)
> + continue;
> +
> + if (res->flags & IORESOURCE_IO) {
> + /* Setup IO mapped memory accesses */
> + ret = pci_ioremap_io(0, res->start);
> + if (ret)
> + return 1;
> +
> + /* Correct addresses for remapped IO */
> + res->end = res->end - res->start;
> + res->start = 0;
> + }
> +
> + rcar_pcie_setup_window(i, res, pcie);
> + pci_add_resource(&sys->resources, res);
> + }
This assumes that the start of the I/O window is always at
bus address 0, and that you have only one PCI host in the system.
Are both guaranteed through the hardware design?
> +static void __init rcar_pcie_enable(struct rcar_pcie *pcie)
> +{
> + struct platform_device *pdev = to_platform_device(pcie->dev);
> + struct hw_pci hw;
> +
> + memset(&hw, 0, sizeof(hw));
> +
> + hw.nr_controllers = 1;
> + hw.private_data = (void **)&pcie;
> + hw.setup = rcar_pcie_setup,
> + hw.map_irq = of_irq_parse_and_map_pci,
> + hw.ops = &rcar_pcie_ops,
You can write this slightly nicer doing
struct hw_pci hw = {
.nr_controllers = 1,
.private_data = (void **)&pcie,
...
};
> +static int __init rcar_pcie_phy_init_rcar_h1(struct rcar_pcie *pcie)
> +{
> + unsigned int timeout = 10;
> +
> + /* Initialize the phy */
> + phy_write_reg(pcie, 0, 0x42, 0x1, 0x0EC34191);
> + phy_write_reg(pcie, 1, 0x42, 0x1, 0x0EC34180);
> + phy_write_reg(pcie, 0, 0x43, 0x1, 0x00210188);
> + phy_write_reg(pcie, 1, 0x43, 0x1, 0x00210188);
> + phy_write_reg(pcie, 0, 0x44, 0x1, 0x015C0014);
> + phy_write_reg(pcie, 1, 0x44, 0x1, 0x015C0014);
> + phy_write_reg(pcie, 1, 0x4C, 0x1, 0x786174A0);
Have you considered moving this into a separate PHY driver?
There are probably good reasons either way, so I'm not asking you
to do it, just to think about what would be best for this driver.
It seems that you already have two different implementations
that only vary in how they access the PHY, so moving that
into a separate driver would keep the knowledge out of the
host driver. OTOH, the PHY registers look like they are part of
the pci host itself.
> + /*
> + * For target transfers, setup a single 64-bit 4GB mapping at address
> + * 0. The hardware can only map memory that starts on a power of two
> + * boundary, and size is power of 2, so best to ignore it.
> + */
> + pci_write_reg(pcie, 0, PCIEPRAR(0));
> + pci_write_reg(pcie, 0, PCIELAR(0));
> + pci_write_reg(pcie, 0xfffffff0UL | LAM_PREFETCH |
> + LAM_64BIT | LAR_ENABLE, PCIELAMR(0));
> + pci_write_reg(pcie, 0, PCIELAR(1));
> + pci_write_reg(pcie, 0, PCIEPRAR(1));
> + pci_write_reg(pcie, 0, PCIELAMR(1));
Is this the only reasonable configuration? If not, you might want to
do the same thing as the x-gene PCI driver that is not yet merged,
and parse the 'dma-ranges' property to determine what the mapping
on a particular machine should be.
Most importantly, why don't you use a mapping that includes RAM beyond
the first 4GB?
> +static int __init pcie_init(void)
> +{
> + return platform_driver_probe(&rcar_pcie_driver, rcar_pcie_probe);
> +}
> +subsys_initcall(pcie_init);
Why so early?
Overall, this driver looks pretty good.
Arnd
next prev parent reply other threads:[~2014-03-21 11:04 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-21 10:32 [PATCH v4 0/9] R-Car Gen2 PCIe host driver Phil Edworthy
2014-03-21 10:32 ` [PATCH v4 1/9] PCI: host: rcar: Add Renesas R-Car PCIe driver Phil Edworthy
2014-03-21 11:04 ` Arnd Bergmann [this message]
2014-03-21 13:59 ` Phil.Edworthy
2014-03-21 14:06 ` Ben Dooks
2014-03-21 15:07 ` Arnd Bergmann
2014-03-23 10:05 ` Geert Uytterhoeven
2014-03-21 10:32 ` [PATCH v4 2/9] PCI: host: rcar: Add MSI support Phil Edworthy
2014-03-21 11:17 ` Lucas Stach
2014-03-21 14:15 ` Phil.Edworthy
2014-03-21 14:26 ` Lucas Stach
2014-03-21 14:34 ` Phil.Edworthy
2014-03-21 10:32 ` [PATCH v4 3/9] ARM: shmobile: r8a7790: Add PCIe clock device tree nodes Phil Edworthy
2014-03-21 10:32 ` [PATCH v4 4/9] ARM: shmobile: r8a7791: " Phil Edworthy
2014-03-21 10:32 ` [PATCH v4 5/9] dt-bindings: pci: rcar pcie device tree bindings Phil Edworthy
2014-03-21 11:23 ` Lucas Stach
2014-03-21 14:18 ` Phil.Edworthy
2014-03-21 14:30 ` Lucas Stach
2014-03-21 15:02 ` Phil.Edworthy
[not found] ` <OFC7DD5DAC.D378B300-ON80257CA2.0051ECEE-80257CA2.00529F98@LocalDomain>
2014-03-24 12:04 ` Phil.Edworthy
2014-03-24 12:15 ` Ben Dooks
2014-03-24 12:25 ` Phil.Edworthy
[not found] ` <OF85DD7B1D.716DE42D-ON80257CA5.00443087-80257CA5.004447DB@LocalDomain>
2014-03-24 12:46 ` Phil.Edworthy
2014-03-24 12:53 ` Lucas Stach
2014-03-21 10:32 ` [PATCH v4 6/9] ARM: shmobile: Add PCIe device tree nodes for R8A7790 Phil Edworthy
2014-03-21 15:29 ` Sergei Shtylyov
2014-03-21 14:53 ` Phil.Edworthy
2014-03-21 14:57 ` Arnd Bergmann
2014-03-21 16:40 ` Jason Gunthorpe
2014-03-21 16:42 ` Sergei Shtylyov
2014-03-21 16:31 ` Phil.Edworthy
2014-03-21 16:49 ` Jason Gunthorpe
2014-03-23 10:13 ` Geert Uytterhoeven
2014-03-21 15:32 ` Sergei Shtylyov
2014-03-21 15:06 ` Phil.Edworthy
2014-03-21 10:32 ` [PATCH v4 7/9] ARM: shmobile: Add PCIe device tree nodes for R8A7791 Koelsch board Phil Edworthy
2014-03-21 10:32 ` [PATCH v4 8/9] ARM: koelsch: Add PCIe to defconfig Phil Edworthy
2014-03-21 10:32 ` [PATCH v4 9/9] ARM: koelsch: Add HAVE_ARM_ARCH_TIMER " Phil Edworthy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=27671657.LuGQtNBfqX@wuerfel \
--to=arnd@arndb.de \
--cc=ben.dooks@codethink.co.uk \
--cc=bhelgaas@google.com \
--cc=horms@verge.net.au \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
--cc=magnus.damm@gmail.com \
--cc=phil.edworthy@renesas.com \
--cc=valentine.barshak@cogentembedded.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).