Re: Portable Device Tree Connector -- conceptual

From: Pantelis Antoniou
Date: Fri Jul 01 2016 - 13:04:39 EST


Hi Frank,

> On Jul 1, 2016, at 19:31 , Frank Rowand <frowand.list@xxxxxxxxx> wrote:
>
> On 07/01/16 03:59, Pantelis Antoniou wrote:
>> Hi Frank,
>>
>> Comments inline.
>>
>>> On Jul 1, 2016, at 03:02 , Frank Rowand <frowand.list@xxxxxxxxx> wrote:
>>>
>>> Hi All,
>>>
>>> I've been trying to wrap my head around what Pantelis and Rob have written
>>> on the subject of a device tree representation of a connector for a
>>> daughter board to connect to (eg a cape or a shield) and the representation
>>> of the daughter board. (Or any other physically pluggable object.)
>>>
>>> After trying to make sense of what had been written (or presented via slides
>>> at a conference - thanks Pantelis!), I decided to go back to first principals
>>> of what we are trying to accomplish. I came up with some really simple bogus
>>> examples to try to explain what my thought process is.
>>>
>>> To start with, assume that the device that will eventually be on a daughter
>>> board is first soldered onto the main board. Then the device tree will
>>> look like:
>>>
>>> $ cat board.dts
>>> /dts-v1/;
>>>
>>> / {
>>> #address-cells = < 1 >;
>>> #size-cells = < 1 >;
>>>
>>> tree_1: soc@0 {
>>> reg = <0x0 0x0>;
>>>
>>> spi_1: spi1 {
>>> };
>>> };
>>>
>>> };
>>>
>>> &spi_1 {
>>> ethernet-switch@0 {
>>> compatible = "micrel,ks8995m";
>>> };
>>> };
>>>
>>> #include "spi_codec.dtsi"
>>>
>>> $ cat spi_codec.dtsi
>>> &spi_1 {
>>> codec@1 {
>>> compatible = "ti,tlv320aic26";
>>> };
>>> };
>>>
>>>
>>> #----- codec chip on cape
>>>
>>> Then suppose I move the codec chip to a cape. Then I will have the same
>>> exact .dts and .dtsi and everything still works.
>>>
>>>
>>> @----- codec chip on cape, overlay
>>>
>>> If I want to use overlays, I only have to add the version and "/plugin/",
>>> then use the '-@' flag for dtc (both for the previous board.dts and
>>> this spi_codec_overlay.dts):
>>>
>>> $ cat spi_codec_overlay.dts
>>> /dts-v1/;
>>>
>>> /plugin/;
>>>
>>> &spi_1 {
>>> codec@1 {
>>> compatible = "ti,tlv320aic26";
>>> };
>>> };
>>>
>>
>> The correct form now for the /plugin/ declaration should be like
>>
>> /dts-v1/ /plugin/;
>>
>> The old method still works for backward compatibility.
>>
>> In fact with the new patches you donât even /plugin/ since when
>> compiling an overlay we can turn on the plugin flag by looking
>> at the output type (dtbo).
>>
>>>
>>> #----- codec chip on cape, overlay, connector
>>>
>>> Now we move into the realm of connectors. My mental model of what the
>>> hardware and driver look like has not changed. The only thing that has
>>> changed is that I want to be able to specify that the connector that
>>> the cape is plugged into has some pins that are the spi bus /soc/spi1.
>>>
>>
>> Thatâs not nearly enough. You might have extra
>> gpio/interrupt/dma/gpmc(memory-controller) pins.
>
> Yes.
>
> I was keeping the example _very_ simple. I was trying to illustrate
> the _concept_, not provide a full implementation.
>
> In a real use, the connector node would provide a node for each of the
> things routed to the connector.
>

We need the example of how to handle pinmux cause itâs the trickiest
thing of all.

>
>> We can disregard dma and gpmc like interfaces for now but gpio and
>> interrupt pins are required.
>>
>> For instance the spi device might have an extra gpio that itâs using
>> to signal some kind of condition (for example low-battery) which an
>> application (not just the kernel) can use to make a platform specific
>> decision.
>>
>>> The following _almost_ but not quite gets me what I want. Note that
>>> the only thing the connector node does is provide some kind of
>>> pointer or reference to what node(s) are physically routed through
>>> the connector. (This node will turn out to not actually work in
>>> this example.)
>>>
>>> $ cat board_with_connector.dts
>>> /dts-v1/;
>>>
>>> / {
>>> #address-cells = < 1 >;
>>> #size-cells = < 1 >;
>>>
>>> tree_1: soc@0 {
>>> reg = <0x0 0x0>;
>>>
>>> spi_1: spi1 {
>>> };
>>> };
>>>
>>> connector_1: connector_1 {
>>> spi1 {
>>> target_phandle = <&spi_1>;
>>> target_path = "/soc/spi1";
>>> };
>>> };
>>>
>>> };
>>>
>>> &spi_1 {
>>> ethernet-switch@0 {
>>> compatible = "micrel,ks8995m";
>>> };
>>> };
>>>
>>> $ cat spi_codec_overlay_with_connector.dts
>>> /dts-v1/;
>>>
>>> /plugin/;
>>>
>>> &connector_1 {
>>> spi1 {
>>> codec@1 {
>>> compatible = "ti,tlv320aic26";
>>> };
>>> };
>>> };
>>
>> This is a subset of whatâs supported by the patch Iâve sent out.
>
> Yes. Same comment as above.
>
>
>> Your example works as long as you assume that thereâs no pinmuxing
>> related to the configuration of the spi controller when routed out
>> to the connector pins.
>
> No. Pinmuxing is part of the host board dts.
>

It is part of the host board DTS yes, but the connector must have
a way to set the pinmux configuration according what the detected
expansion board expects.

> The physical connector does not change the way that pinmuxing
> works. It is just the same as if there were wires physically
> connected (soldered) between the daughter board and the main
> board.
>

The physical properties of the pin of the connector do not change.

However the routing of functions in the SoC do change.

By default most of the pins on the connector are HiZ or set to input when
no expansion board is connected. The only fixed function pins that are
known and configured by the host board dts are those that are used by
the host boardâs identification scheme (i.e. I2C EEPROM, set of GPIO inputs
etc).

When an expansion board is connected upon boot and probing of the the expansion
board manager device it will use a method that is using the configured detection
pins to identify it.

After getting the ID it is going to find a corresponding overlay to apply.

This overlay will have to configure each pin accordingly.

It is perfectly for a pin on a connector to be a GPIO output for expansion
board A, I2C bus SDA for board B, etc...

So there has to be a way to get the pinmux configuration according to the
required connection function on each pin in use.

>
>> In reality there are may be many possible option of the same
>> hardware block (spi/i2c) to be routed to different pins on the
>> connector.
>>
>> You might get by if you have a number of selectable pre-canned
>> spi configuration that are selected.
>
> Again, just the same as if the connector did not exist and
> everything is hardwired.
>
> The connector node for the host board would contain a node for
> each of the alternative uses of the pins.
>

Right.

>
>> For instance if there are two spi controllers each of which have
>> two different pinout options on the connector you would address
>> each as a different spi controller on the connector, but then
>> youâd end up with
>>
>> spi_connector_0 -> spi_0_mux_0
>> spi_connector_1 -> spi_0_mux_1
>> spi_connector_2 -> spi_1_mux_0
>> spi_connector_3 -> spi_1_mux_1
>
> Yes. But again, exactly the same as if the daughter board was
> hard wired with no intervening physical connector.
>

Yes.

>
>> It gets hairy though pretty fast with modern SoCs with extensive
>> muxing options.
>>
>>>
>>> The result is that the overlay fixup for spi1 on the cape will
>>> relocate the spi1 node to /connector_1 in the host tree, so
>>> this does not solve the connector linkage yet:
>>>
>>> -- chunk from the decompiled board_with_connector.dtb:
>>>
>>> __symbols__ {
>>> connector_1 = "/connector_1";
>>> };
>>>
>>> -- chunk from the decompiled spi_codec_overlay_with_connector.dtb:
>>>
>>> fragment@0 {
>>> target = <0xffffffff>;
>>> __overlay__ {
>>> spi1 {
>>> codec@1 {
>>> compatible = "ti,tlv320aic26";
>>> };
>>> };
>>> };
>>> };
>>> __fixups__ {
>>> connector_1 = "/fragment@0:target:0";
>>> };
>>>
>>>
>>> #----- magic new dtc syntax
>>>
>>> What I really want is some way to tell dtc that I want to do one
>>> level of dereferencing when resolving the path of device nodes
>>> contained by the connector node in the overlay dts.
>>>
>>> The exact syntax does not matter here, I am just trying to get the
>>> concept. I will add the not yet implemented dtc feature of
>>> "/connector/" to the connector node in both the tree dts and the
>>> overlay dts, and show how the output of dtc would change. The
>>> "/connector/" directive tells dtc that for a base dts (hand
>>> waving how it knows base vs overlay dts file) to look into
>>> each node at that level and determine what other node it
>>> maps to (again, hand waving, in this example just to
>>> show the linkage, I have hard coded both the path and the
>>> phandle of the target node that the connector child node
>>> maps to). The "/connector/" directive tells dtc that for
>>> an overlay dts (again hand waving) to provide a fixup for
>>> each child node.
>>>
>>> $ cat board_with_connector_v2.dts
>>> /dts-v1/;
>>>
>>> / {
>>> #address-cells = < 1 >;
>>> #size-cells = < 1 >;
>>>
>>> tree_1: soc@0 {
>>> reg = <0x0 0x0>;
>>>
>>> spi_1: spi1 {
>>> };
>>> };
>>>
>>> connector_1: connector_1 {
>>> /connector/;
>>> spi1 {
>>> target_phandle = <&spi_1>;
>>> target_path = "/soc/spi1";
>>> };
>>> };
>>>
>>> };
>>>
>>> &spi_1 {
>>> ethernet-switch@0 {
>>> compatible = "micrel,ks8995m";
>>> };
>>> };
>>>
>>> $ cat spi_codec_overlay_with_connector_v2.dts
>>>
>>> /dts-v1/;
>>>
>>> /plugin/;
>>>
>>> &connector_1 {
>>> /connector/;
>>> spi1 {
>>> codec@1 {
>>> compatible = "ti,tlv320aic26";
>>> };
>>> };
>>> };
>>>
>>> -- chunk from the decompiled board_with_connector_v2.dtb:
>>>
>>> __symbols__ {
>>> connector_1 {
>>> spi1 = "/soc@0/spi1";
>>> };
>>> };
>>>
>>> -- chunk from the decompiled spi_codec_overlay_with_connector_v2.dtb:
>>>
>>> / {
>>>
>>> fragment@0 {
>>> target = <0xffffffff>;
>>> __overlay__ {
>>> spi1 {
>>> codec@1 {
>>> compatible = "ti,tlv320aic26";
>>> };
>>> };
>>> };
>>> };
>>> __fixups__ {
>>> connector_1 {
>>> spi1 = "/fragment@0/__overlay__:spi1:0";
>>> };
>>> };
>>>
>>> Of course the overlay loader will also have to be modified to understand
>>> the new information.
>>>
>>> Exact format of the __symbols__ and __fixups__ are implementation
>>> details, I am just trying to present the model.
>>>
>>> Ignoring device tree source syntax and dtc implementation issues, does
>>> this conceptual model look more straight forward and a better direction
>>> for how to represent connectors?
>>>
>>
>> We could use dtc sugar to get to something more elegant, I need some time
>> to think about this a bit longer.
>>
>>> -Frank
>>
>> Regards
>>
>> â Pantelis

Regards

â Pantelis