Hi Frank, > On Jul 1, 2016, at 21:21 , Frank Rowand <frowand.list@xxxxxxxxx> wrote: > > On 07/01/16 09:56, Pantelis Antoniou wrote: >> 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. > > Again, this is exactly the same concept as if the daughter board was soldered > directly to the host board with no connector involved. The pinmux > configuration has nothing to do with the physical connector, it is already > described by the pinmux information in the host board .dtb. The connector > node in the host .dtb does not need to duplicate any of that information. > > There already is a pinmux mechanism in place to choose which of the > possible alternative uses of a set of pins is in use at any point > in time. The choice of active functionality can be changed at > any time. > > The pinmux configuration is already in place in the host board .dtb. > The host board .dtb connector node only provides a mapping to what > other nodes have hardware blocks that have signals that are routed > to the physical connector. There is no need for the connector node > to be concerned with any of the details of those other nodes -- the > other nodes already specify the details. > The mechanism to choose which of the possible alternative uses is geared to select between a different set of configuration settings for the same device. I.e. “default” -> working configuration, “powersave” -> put the pins in power save mode, etc. I get what you’re saying but the details about pinmuxing are the killer. Can you please spend some time and come up with an example which we can use as a basis for discussion? >>>> 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 Regards — Pantelis -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html