[PATCH v2 07/10] ARM: tegra: pcie: Add device tree support
Thierry Reding
thierry.reding at avionic-design.de
Fri Jun 22 22:43:11 EST 2012
On Fri, Jun 22, 2012 at 05:46:52AM -0600, Bjorn Helgaas wrote:
> On Fri, Jun 22, 2012 at 5:00 AM, Thierry Reding
> <thierry.reding at avionic-design.de> wrote:
> > On Fri, Jun 22, 2012 at 04:18:05AM -0600, Bjorn Helgaas wrote:
> >> On Thu, Jun 21, 2012 at 12:47 AM, Thierry Reding
> >> <thierry.reding at avionic-design.de> wrote:
> >> > On Tue, Jun 19, 2012 at 11:31:39AM -1000, Mitch Bradley wrote:
> >>
> >> >> Version A - 3 address cells: In this version, the intermediate
> >> >> address space has 3 cells: port#, address type, offset. Address
> >> >> type is
> >> >> 0 : root port
> >> >> 1 : config space
> >> >> 2 : extended config space
> >> >> 3 : I/O
> >> >> 4 : non-prefetchable memory
> >> >> 5 : prefetchable memory.
> >> >>
> >> >> The third cell "offset" is necessary so that the size field has a
> >> >> number space that can include it.
> >> >>
> >> >> pcie-controller {
> >> >> compatible = "nvidia,tegra20-pcie";
> >> >> reg = <0x80003000 0x00000800 /* PADS registers */
> >> >> 0x80003800 0x00000200>; /* extended configuration space */
> >> >> interrupts = <0 98 0x04 /* controller interrupt */
> >> >> 0 99 0x04>; /* MSI interrupt */
> >> >> status = "disabled";
> >> >>
> >> >> ranges = <0 0 0 0x80000000 0x00001000 /* Root port 0 */
> >> >> 0 1 0 0x80004000 0x00080000 /* Port 0 config space */
> >> >> 0 2 0 0x80104000 0x00080000 /* Port 0 ext config space *
> >> >> 0 3 0 0x80400000 0x00008000 /* Port 0 downstream I/O */
> >> >> 0 4 0 0x90000000 0x08000000 /* Port 0 non-prefetchable memory */
> >> >> 0 5 0 0xa0000000 0x08000000 /* Port 0 prefetchable memory */
> >> >>
> >> >> 1 0 0 0x80001000 0x00001000 /* Root port 1 */
> >> >> 1 1 0 0x80004000 0x00080000 /* Port 1 config space */
> >> >> 1 2 0 0x80184000 0x00080000 /* Port 1 ext config space */
> >> >> 1 3 0 0x80408000 0x00010000 /* Port 1 downstream I/O */
> >> >> 1 4 0 0x98000000 0x08000000 /* Port 1 non-prefetchable memory */
> >> >> 1 5 0 0xa0000000 0x08000000>; /* Port 1 prefetchable memory */
> >> >>
> >> >> #address-cells = <3>;
> >> >> #size-cells = <1>;
> >> >>
> >> >> pci at 0 {
> >> >> reg = <0 0 0 0x1000>;
> >> >> status = "disabled";
> >> >>
> >> >> #address-cells = <3>;
> >> >> #size-cells = <2>;
> >> >>
> >> >> ranges = <0x80000000 0 0 0 1 0 0 0x00080000 /* config */
> >> >> 0x90000000 0 0 0 2 0 0 0x00080000 /* extended config */
> >> >> 0x81000000 0 0 0 3 0 0 0x00008000 /* I/O */
> >> >> 0x82000000 0 0 0 4 0 0 0x08000000 /* non-prefetchable memory */
> >> >> 0xc2000000 0 0 0 5 0 0 0x08000000>; /* prefetchable memory */
> >> >>
> >> >> nvidia,ctrl-offset = <0x110>;
> >> >> nvidia,num-lanes = <2>;
> >> >> };
> >> >>
> >> >>
> >> >> pci at 1 {
> >> >> reg = <1 0 0 0x1000>;
> >> >> status = "disabled";
> >> >>
> >> >> #address-cells = <3>;
> >> >> #size-cells = <2>;
> >> >>
> >> >> ranges = <0x80000000 0 0 1 1 0 0 0x00080000 /* config */
> >> >> 0x90000000 0 0 1 2 0 0 0x00080000 /* extended config */
> >> >> 0x81000000 0 0 1 3 0 0 0x00008000 /* I/O */
> >> >> 0x82000000 0 0 1 4 0 0 0x08000000 /* non-prefetchable memory */
> >> >> 0xc2000000 0 0 1 5 0 0 0x08000000>; /* prefetchable memory */
> >> >>
> >> >> nvidia,ctrl-offset = <0x118>;
> >> >> nvidia,num-lanes = <2>;
> >> >> };
> >>
> >> I'm not familiar with device tree, so pardon me if these are stupid
> >> questions. These seem to be describing PCI host bridges.
> >
> > Yes, correct.
> >
> >> I assume some of these ranges describe MMIO, prefetchable MMIO, and
> >> I/O port apertures that the bridge forwards to the PCI bus.
> >
> > Yes.
> >
> >> Is there provision for any address offset applied by the bridge when
> >> it forwards downstream? (Maybe these bridges don't apply any offset?)
> >> "0xa0000000 0x08000000" appears for both ports 0 and 1 prefetchable
> >> memory; I don't know if that's an error, an indication that each
> >> bridge applies a different offset, or that both bridges forward the
> >> same aperture (I hope not the latter, because Linux can't really deal
> >> with that).
> >
> > That seems to be a typo. It should have been 0xa8000000 in the second
> > case. The PCIe controller has registers that are programmed with the
> > aperture for the configuration and extended configuration spaces, as
> > well as the downstream I/O, prefetchable and non-prefetchable memory
> > regions.
> >
> > The configuration spaces aren't actually forwarded by the bridges, but
> > are handled only by the controller.
>
> Right. The host bridge (controller) would convert memory accesses on
> the upstream side into PCI config accesses on its downstream PCI
> interface.
>
> > The other apertures are programmed
> > into the bridges using standard PCI registers.
>
> If you're talking about programming host bridge apertures, there are
> no "standard PCI registers" to do that. The programming model of the
> host bridge itself is not part of the PCI spec. PCI-to-PCI bridge
> apertures *are* specified by the PCI Bridge spec, so those are
> standard.
Each of the root ports has a PCI-compatible set of configuration
registers, so I guess what is meant is that the apertures a programmed
according to the PCI bridge specification.
> >> Is the bus number aperture included somewhere? How do we know what
> >> bus numbers are available for allocation under each bridge?
> >
> > Not yet. I don't think DT imposes a bus number allocation on PCI
> > bridges. However the matching of DT nodes to PCI bridges is done based
> > on the bus number. For that you provide a bus-ranges property which
> > defines the bus aperture of the given PCI bridge. The DT matching code
> > compares the first cell of this property with the primary bus number of
> > the bridge.
>
> I don't fully understand this, but I can tell you that things don't
> work very well if we don't know the aperture. We can make
> assumptions, like the root bus is 00, and then enumerate everything
> reachable from there. But then all we know is the largest bus number
> actually reachable from bus 00, which is usually smaller then the end
> of the aperture. We don't know how many unused bus numbers there are
> in the aperture, so we can't safely allocate any for hot-added
> devices.
I think DT support for PCI is lacking in a lot of areas. PowerPC seems
to be the only architecture actively setting up busses according to the
bus-range property specified in the DT. All other architectures seem to
not pre-allocate bus apertures and go with the default instead. From
what you say that means hot-plugging is out. Although I don't think the
Tegra PCIe controller even supports hot-plugging.
> > This is in fact somewhat counter-productive because it requires you to
> > hard-code the PCI hierarchy within the DT and you loose a lot of the
> > probing functionality. This is not much of an issue for typical PCI
> > endpoints (like network cards) but becomes a problem if you have a PCI
> > endpoint that implements an I2C bus and you want to match I2C slaves on
> > that bus to device nodes so that the kernel can parse and instantiate
> > them properly. I guess in the latter cases hard-coding the PCI tree in
> > DT is not actually a drawback, though.
> >
> >> I see mention of config space. Is some of that referring to the ECAM
> >> as in 7.2.2 of the PCIe spec v3.0 (what we refer to as MMCONFIG on
> >> x86)?
> >
> > I only have access to the PCIe 2.0 specification, but it seems to
> > contain the same 7.2.2 section. In fact it looks as though this
> > particular controller indeed implements something similar to ECAM. The
> > address mapping is a little different, though:
> >
> > A[(16 + n - 1):16]: bus number
> > A[15:11]: device number
> > A[10:8]: function number
> > A[7:2]: register number
> > A[1:0]: unused
> >
> > That information comes directly from the driver and I have no access to
> > the corresponding documentation. It seems like the extended
> > configuration space is accessed using the same mapping but starting at a
> > different base address.
> >
> > But now that you mention it, maybe the driver code is buggy here, and
> > the controller indeed implements ECAM. Furthermore it also seems like
> > the current code doesn't work for the extended configuration space
> > because while the correct offset into the extended configuration space
> > is chosen, the access to registers is done using the same mapping as
> > above, so instead of the 12 (10) bits required for the register number
> > only 8 (6) are in fact used.
> >
> > I wonder whether anyone's actually tested this.
> >
> > Stephen: can you try to find out whether the Tegra PCIe controller
> > indeed implements ECAM, or if this scheme is actually just a proprietary
> > variant?
>
> It'd be a real shame if they made up a proprietary scheme when ECAM
> seems to be required by the spec. I'm interested because the current
> MMCONFIG code seems unnecessarily x86-specific, and I expect every
> arch with PCIe would want to use ECAM, so maybe there's some chance
> for a generic implementation.
Since this is pretty well specified by PCIe, a generic implementation
should be possible. We'll have to wait for some better documentation on
Tegra to know whether this is actually ECAM or not.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/devicetree-discuss/attachments/20120622/92ed485b/attachment-0001.sig>
More information about the devicetree-discuss
mailing list