[RFC] PCI: BCM5301X: add PCIe2 driver for BCM5301X SoCs
Arnd Bergmann
arnd at arndb.de
Sun Nov 9 12:27:40 PST 2014
On Saturday 08 November 2014 22:26:58 Hauke Mehrtens wrote:
> On 11/08/2014 08:47 PM, Arnd Bergmann wrote:
> > On Saturday 08 November 2014 19:13:12 Hauke Mehrtens wrote:
> >
> >> diff --git a/drivers/pci/host/pci-host-bcm5301x.c b/drivers/pci/host/pci-host-bcm5301x.c
> >> new file mode 100644
> >> index 0000000..8b7ba62
> >> --- /dev/null
> >> +++ b/drivers/pci/host/pci-host-bcm5301x.c
> >> @@ -0,0 +1,483 @@
> >> +/*
> >> + * Northstar PCI-Express driver
> >> + * Only supports Root-Complex (RC) mode
> >> + *
> >> + * Notes:
> >> + * PCI Domains are being used to identify the PCIe port 1:1.
> >> + *
> >> + * Only MEM access is supported, PAX does not support IO.
> >
> > What is PAX?
>
> This is the name of the PCIe controller I think, This was copied from
> the vendor driver, I hope Florian knows more details.
Just clarify this in the comment.
> >> +static int bcma_pcie2_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
> >> +{
> >> + struct pci_sys_data *sys = pdev->sysdata;
> >> + struct bcma_device *bdev = sys->private_data;
> >> +
> >> + /*
> >> + * Every PCIe controller has 5 IRQ number and the last one is
> >> + * triggered every time, use that one
> >> + */
> >> + if (bdev && bdev->dev.of_node)
> >> + return irq_of_parse_and_map(bdev->dev.of_node, 4);
> >> +
> >> + return bdev->irq;
> >> +}
> >
> > If you have an OF device node for the PCI host, you don't need this,
> > there should already be an interrupt-map property that correctly
> > maps this into the interrupt domain of the bcma bus, so you can use
> > the default of_irq_parse_and_map_pci function.
>
> So I just have to define a interrupt-map property for the device this
> driver gets registered for and then I can use the default implementation?
It depends on what you want to cover. For all I know, you normally don't
need a DT entry for this PCI host, as it's covered by the upstream bus.
However adding a DT node would let you do some things that you can't
currently do:
- specify the inbound and outbound windows to configure
- list different interrupts, e.g. if there is a PCIe-to-PCI bridge
and the device connected to it is routed to a GPIO pin or the
another input of the main interrupt controller.
> >> +static u32 bcma_pcie2_cfg_base(struct bcma_device *bdev, int busno,
> >> + unsigned int devfn, int where)
> >> +{
> >> + int slot = PCI_SLOT(devfn);
> >> + int fn = PCI_FUNC(devfn);
> >> + u32 addr_reg;
> >> +
> >> + if (busno == 0) {
> >> + if (slot >= 1)
> >> + return 0;
> >> + bcma_write32(bdev, BCMA_CORE_PCIE2_CONFIGINDADDR,
> >> + where & 0xffc);
> >> + return BCMA_CORE_PCIE2_CONFIGINDDATA;
> >> + }
> >> + if (fn > 1)
> >> + return 0;
> >> + addr_reg = (busno & 0xff) << 20 | (slot << 15) | (fn << 12) |
> >> + (where & 0xffc) | (1 & 0x3);
> >> +
> >> + bcma_write32(bdev, BCMA_CORE_PCIE2_CFG_ADDR, addr_reg);
> >> + return BCMA_CORE_PCIE2_CFG_DATA;
> >> +}
> >
> > The normal buses seem to be ECAM compliant, I wonder if we can have the
> > code to access those shared between this driver, pci-host-generic.c and
> > the ACPI PCI implementation.
>
> There are just a few lines we can share I do not think that would be
> worth the effort.
Well, the idea would be that for the root bus, you use simplified pci_ops
that just do BCMA_CORE_PCIE2_CONFIGINDADDR/DATA, while for the other
buses you use the standard pci ops.
> > Which code depends on this? I think I've seem something similar in
> > other host drivers, so maybe we can change the core code instead.
>
> It is used in many places in the core PCI code, I think it is better to
> change this to the correct value, but the pci-tegra.c driver does it in
> a better way, by adding a DECLARE_PCI_FIXUP_EARLY only changing the
> struct data, I will use that version.
Yes, sounds good.
> >> + /*
> >> + * Inbound address translation setup
> >> + * Northstar only maps up to 128 MiB inbound, DRAM could be up to 1 GiB.
> >> + *
> >> + * For now allow access to entire DRAM, assuming it is less than 128MiB,
> >> + * otherwise DMA bouncing mechanism may be required.
> >> + * Also consider DMA mask to limit DMA physical address
> >> + */
> >> + /* 64-bit LE regs, write low word, high is 0 at reset */
> >> + bcma_write32(bdev, BCMA_CORE_PCIE2_FUNC0_IMAP1, PHYS_OFFSET | 0x1);
> >> + bcma_write32(bdev, BCMA_CORE_PCIE2_IARR1_LOWER,
> >> + PHYS_OFFSET | ((SZ_128M >> 20) & 0xff));
> >
> > Maybe I should bully you into enabling swiotlb on arm32 ;-)
>
> This sounds complicated, I hope I can avoid it. ;-)
I'd really hope that it's not that hard. We basically just need a copy of
coherent_swiotlb_dma_ops/noncoherent_swiotlb_dma_ops from arm64 and
use those on bcma devices, with the right dma_mask set.
Arnd
More information about the linux-arm-kernel
mailing list