Message ID | 20220622173605.1168416-2-pmalani@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | usb: typec: Introduce typec-switch binding | expand |
Quoting Prashant Malani (2022-06-22 10:34:30) > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > new file mode 100644 > index 000000000000..78b0190c8543 > --- /dev/null > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > @@ -0,0 +1,74 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: USB Type-C Switch > + > +maintainers: > + - Prashant Malani <pmalani@chromium.org> > + > +description: > + A USB Type-C switch represents a component which routes USB Type-C data > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > + and cable are operating in. It can also modify lane routing based on > + the orientation of a connected Type-C peripheral. > + > +properties: > + compatible: > + const: typec-switch > + > + mode-switch: > + type: boolean > + description: Specify that this switch can handle alternate mode switching. > + > + orientation-switch: > + type: boolean > + description: Specify that this switch can handle orientation switching. > + > + ports: > + $ref: /schemas/graph.yaml#/properties/ports > + description: OF graph binding modelling data lines to the Type-C switch. > + > + properties: > + port@0: > + $ref: /schemas/graph.yaml#/properties/port > + description: Link between the switch and a Type-C connector. Is there an update to the usb-c-connector binding to accept this port connection? > + > + required: > + - port@0 > + > +required: > + - compatible > + - ports > + > +anyOf: > + - required: > + - mode-switch > + - required: > + - orientation-switch > + > +additionalProperties: true > + > +examples: > + - | > + drm-bridge { > + usb-switch { > + compatible = "typec-switch"; I still don't understand the subnode design here. usb-switch as a container node indicates to me that this is a bus, but in earlier rounds of this series it was stated this isn't a bus. Why doesn't it work to merge everything inside usb-switch directly into the drm-bridge node? > + mode-switch; > + orientation-switch; > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > + reg = <0>; > + anx_ep: endpoint { > + remote-endpoint = <&typec_controller>; > + }; > + }; > + }; > + };
On Thu, Jun 23, 2022 at 11:30 AM Stephen Boyd <swboyd@chromium.org> wrote: > > Quoting Prashant Malani (2022-06-22 10:34:30) > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > new file mode 100644 > > index 000000000000..78b0190c8543 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > @@ -0,0 +1,74 @@ > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: USB Type-C Switch > > + > > +maintainers: > > + - Prashant Malani <pmalani@chromium.org> > > + > > +description: > > + A USB Type-C switch represents a component which routes USB Type-C data > > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > > + and cable are operating in. It can also modify lane routing based on > > + the orientation of a connected Type-C peripheral. > > + > > +properties: > > + compatible: > > + const: typec-switch > > + > > + mode-switch: > > + type: boolean > > + description: Specify that this switch can handle alternate mode switching. > > + > > + orientation-switch: > > + type: boolean > > + description: Specify that this switch can handle orientation switching. > > + > > + ports: > > + $ref: /schemas/graph.yaml#/properties/ports > > + description: OF graph binding modelling data lines to the Type-C switch. > > + > > + properties: > > + port@0: > > + $ref: /schemas/graph.yaml#/properties/port > > + description: Link between the switch and a Type-C connector. > > Is there an update to the usb-c-connector binding to accept this port > connection? Not at this time. I don't think we should enforce that either. (Type-C data-lines could theoretically be routed through intermediate hardware like retimers/repeaters) > > > + > > + required: > > + - port@0 > > + > > +required: > > + - compatible > > + - ports > > + > > +anyOf: > > + - required: > > + - mode-switch > > + - required: > > + - orientation-switch > > + > > +additionalProperties: true > > + > > +examples: > > + - | > > + drm-bridge { > > + usb-switch { > > + compatible = "typec-switch"; > > I still don't understand the subnode design here. usb-switch as a > container node indicates to me that this is a bus, but in earlier rounds > of this series it was stated this isn't a bus. I am not aware of this as a requirement. Can you please point me to the documentation that states this needs to be the case? > Why doesn't it work to > merge everything inside usb-switch directly into the drm-bridge node? I attempted to explain the rationale in the previous version [1], but using a dedicated sub-node means the driver doesn't haven't to inspect individual ports to determine which of them need switches registered for them. If it sees a `typec-switch`, it registers a mode-switch and/or orientation-switch. IMO it simplifies the hardware device binding too. It also maps with the internal block diagram for these hardware components (for ex. the anx7625 crosspoint switch is a separate sub-block within anx7625). [1] https://lore.kernel.org/linux-usb/CACeCKaeH6qTTdG_huC4yw0xxG8TYEOtfPW3tiVNwYs=P4QVPXg@mail.gmail.com/ > > > + mode-switch; > > + orientation-switch; > > + ports { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + port@0 { > > + reg = <0>; > > + anx_ep: endpoint { > > + remote-endpoint = <&typec_controller>; > > + }; > > + }; > > + }; > > + };
Quoting Prashant Malani (2022-06-23 12:08:21) > On Thu, Jun 23, 2022 at 11:30 AM Stephen Boyd <swboyd@chromium.org> wrote: > > > > Quoting Prashant Malani (2022-06-22 10:34:30) > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > new file mode 100644 > > > index 000000000000..78b0190c8543 > > > --- /dev/null > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > @@ -0,0 +1,74 @@ > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > +%YAML 1.2 [...] > > > + ports: > > > + $ref: /schemas/graph.yaml#/properties/ports > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > + > > > + properties: > > > + port@0: > > > + $ref: /schemas/graph.yaml#/properties/port > > > + description: Link between the switch and a Type-C connector. > > > > Is there an update to the usb-c-connector binding to accept this port > > connection? > > Not at this time. I don't think we should enforce that either. > (Type-C data-lines could theoretically be routed through intermediate > hardware like retimers/repeaters) I'm mostly wondering if having such a connection to the usb-c-connector, or even through some retimer/repeater, would be sufficient to detect how many type-c ports are connected to the device. If the type-c pin assignments only support two or four lanes for DP then it seems like we should describe the two lanes or four lanes as one graph endpoint "output" and then have some 'data-lanes' property in case the DP lanes are flipped while being sent to the retimer or usb-c-connector. This would of course depend on the capability of the device, i.e. if it can remap DP lanes or only has 2 lanes of DP, etc. > > > + - | > > > + drm-bridge { > > > + usb-switch { > > > + compatible = "typec-switch"; > > > > I still don't understand the subnode design here. usb-switch as a > > container node indicates to me that this is a bus, but in earlier rounds > > of this series it was stated this isn't a bus. > > I am not aware of this as a requirement. Can you please point me to the > documentation that states this needs to be the case? I'm not aware of any documentation for the dos and don'ts here. Are there any examples in the bindings directory that split up a device into subnodes that isn't in bindings/mfd? I just know from experience that any time I try to make a child node of an existing node that I'm supposed to be describing a bus, unless I'm adding some sort of exception node like a graph binding or an opp table. Typically a node corresponds 1:1 with a device in the kernel. I'll defer to Rob for any citations. > > > Why doesn't it work to > > merge everything inside usb-switch directly into the drm-bridge node? > > I attempted to explain the rationale in the previous version [1], but > using a dedicated sub-node means the driver doesn't haven't to > inspect individual ports to determine which of them need switches > registered for them. If it sees a `typec-switch`, it registers a > mode-switch and/or orientation-switch. IMO it simplifies the hardware > device binding too. How is that any harder than hard-coding that detail into the driver about which port and endpoint is possibly connected to the usb-c-connector (or retimer)? All of that logic could be behind some API that registers a typec-switch based on a graph port number that's passed in, ala drm_of_find_panel_or_bridge()'s design. Coming from a DT writer's perspective, I just want to go through the list of output pins in the datasheet and match them up to the ports binding for this device. If it's a pure DP bridge, where USB hardware isn't an input or an output like the ITE chip, then I don't want to have to describe a port graph binding for the case when it's connected to a dp-connector (see dp-connector.yaml) in the top-level node and then have to make an entirely different subnode for the usb-c-connector case with a whole other set of graph ports. How would I even know which two differential pairs correspond to port0 or port1 in this binding in the ITE case? Ideally we make the graph binding more strict for devices by enforcing that their graph ports exist. Otherwise we're not fully describing the connections between devices and our dtb checkers are going to let things through where the driver most likely will fail because it can't figure out what to do, e.g. display DP on 4 lanes or play some DP lane rerouting games to act as a mux. > > It also maps with the internal block diagram for these hardware > components (for ex. the anx7625 crosspoint switch is a separate > sub-block within anx7625). We don't make DT bindings for sub-components like this very often. It would make more sense to me to have a subnode if a typec switch was some sort of off the shelf hard macro that the hardware engineer placed down inside the IC that they delivered. Then we could have a completely generic driver that binds to the generic binding that knows how to drive the hardware, because it's an unchangeable hard macro with a well defined programming interface. > > [1] https://lore.kernel.org/linux-usb/CACeCKaeH6qTTdG_huC4yw0xxG8TYEOtfPW3tiVNwYs=P4QVPXg@mail.gmail.com/ I looked at the fsa4480 driver and the device has a publicly available datasheet[2]. That device is designed for "audio accessory mode" but I guess it's being used to simply mux SBU lines? There isn't an upstream user of the binding so far, but it also doesn't look like a complete binding. I'd expect to see DN_L/R as a graph output connected to the usb-c-connector and probably have a usb2.0 input port and a 'sound-dai' property to represent the input audio path. Finally, simply connecting to the typec controller node isn't sufficient because a typec controller can be controlling many usb-c-connectors so I don't see how the graph binding would be able to figure out how many usb-c-connectors are connected to a mux like device, unless we took the approach of this patch. Is that why you're proposing this binding? To avoid describing a graph binding in the usb-c-connector and effectively "pushing" the port count up to the mux? [2] https://www.onsemi.com/pdf/datasheet/fsa4480-d.pdf
On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > Quoting Prashant Malani (2022-06-23 12:08:21) > > On Thu, Jun 23, 2022 at 11:30 AM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > Quoting Prashant Malani (2022-06-22 10:34:30) > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > new file mode 100644 > > > > index 000000000000..78b0190c8543 > > > > --- /dev/null > > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > @@ -0,0 +1,74 @@ > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > > +%YAML 1.2 > [...] > > > > + ports: > > > > + $ref: /schemas/graph.yaml#/properties/ports > > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > > + > > > > + properties: > > > > + port@0: > > > > + $ref: /schemas/graph.yaml#/properties/port > > > > + description: Link between the switch and a Type-C connector. > > > > > > Is there an update to the usb-c-connector binding to accept this port > > > connection? > > > > Not at this time. I don't think we should enforce that either. > > (Type-C data-lines could theoretically be routed through intermediate > > hardware like retimers/repeaters) > > I'm mostly wondering if having such a connection to the usb-c-connector, > or even through some retimer/repeater, would be sufficient to detect how > many type-c ports are connected to the device. If the type-c pin > assignments only support two or four lanes for DP then it seems like we > should describe the two lanes or four lanes as one graph endpoint > "output" and then have some 'data-lanes' property in case the DP lanes > are flipped while being sent to the retimer or usb-c-connector. This > would of course depend on the capability of the device, i.e. if it can > remap DP lanes or only has 2 lanes of DP, etc. > > > > > + - | > > > > + drm-bridge { > > > > + usb-switch { > > > > + compatible = "typec-switch"; > > > > > > I still don't understand the subnode design here. usb-switch as a > > > container node indicates to me that this is a bus, but in earlier rounds > > > of this series it was stated this isn't a bus. > > > > I am not aware of this as a requirement. Can you please point me to the > > documentation that states this needs to be the case? > > I'm not aware of any documentation for the dos and don'ts here. Are > there any examples in the bindings directory that split up a device into > subnodes that isn't in bindings/mfd? usb-c-connector [3] and its users is an example. > I just know from experience that > any time I try to make a child node of an existing node that I'm > supposed to be describing a bus, unless I'm adding some sort of > exception node like a graph binding or an opp table. Typically a node > corresponds 1:1 with a device in the kernel. I'll defer to Rob for any > citations. > > > > > > Why doesn't it work to > > > merge everything inside usb-switch directly into the drm-bridge node? > > > > I attempted to explain the rationale in the previous version [1], but > > using a dedicated sub-node means the driver doesn't haven't to > > inspect individual ports to determine which of them need switches > > registered for them. If it sees a `typec-switch`, it registers a > > mode-switch and/or orientation-switch. IMO it simplifies the hardware > > device binding too. > > How is that any harder than hard-coding that detail into the driver > about which port and endpoint is possibly connected to the > usb-c-connector (or retimer)? All of that logic could be behind some API > that registers a typec-switch based on a graph port number that's passed > in, ala drm_of_find_panel_or_bridge()'s design. If each driver has to do it (and the port specifics vary for each driver), it becomes an avoidable overhead for each of them. I prefer hard-coding such details if avoidable. I suppose both approaches require modifications to the binding and the driver code. > > Coming from a DT writer's perspective, I just want to go through the > list of output pins in the datasheet and match them up to the ports > binding for this device. If it's a pure DP bridge, where USB hardware > isn't an input or an output like the ITE chip, then I don't want to have > to describe a port graph binding for the case when it's connected to a > dp-connector (see dp-connector.yaml) in the top-level node and then have > to make an entirely different subnode for the usb-c-connector case with > a whole other set of graph ports. This approach still allows for that, if the driver has any use for it (AFAICT these drivers don't). Iff that driver uses it, one can (optionally) route their output (top-level) ports through the "typec-switch" sub-node (and onwards as required). If it's being used in a "pure-DP" configuration, the "typec-switch" just goes away (the top level ports can be routed as desired by the driver). (Again, I must reiterate that neither this driver or the anx driver utilizes this) > > How would I even know which two differential pairs correspond to port0 > or port1 in this binding in the ITE case? Why do we need to know that? It doesn't affect this or the other driver or hardware's functioning in a perceivable way. > Ideally we make the graph > binding more strict for devices by enforcing that their graph ports > exist. Otherwise we're not fully describing the connections between > devices and our dtb checkers are going to let things through where the > driver most likely will fail because it can't figure out what to do, > e.g. display DP on 4 lanes or play some DP lane rerouting games to act > as a mux. How is the current binding enforcing this? The typec-switch binding as a first step ensures that the DT is connecting the hardware(anx,ite etc) to something that at least "claims" to be a Type-C switch. > > > > > It also maps with the internal block diagram for these hardware > > components (for ex. the anx7625 crosspoint switch is a separate > > sub-block within anx7625). > > We don't make DT bindings for sub-components like this very often. It > would make more sense to me to have a subnode if a typec switch was some > sort of off the shelf hard macro that the hardware engineer placed down > inside the IC that they delivered. Then we could have a completely > generic driver that binds to the generic binding that knows how to drive > the hardware, because it's an unchangeable hard macro with a well > defined programming interface. > > > > > [1] https://lore.kernel.org/linux-usb/CACeCKaeH6qTTdG_huC4yw0xxG8TYEOtfPW3tiVNwYs=P4QVPXg@mail.gmail.com/ > > I looked at the fsa4480 driver and the device has a publicly available > datasheet[2]. That device is designed for "audio accessory mode" but I > guess it's being used to simply mux SBU lines? There isn't an upstream > user of the binding so far, but it also doesn't look like a complete > binding. I'd expect to see DN_L/R as a graph output connected to the > usb-c-connector and probably have a usb2.0 input port and a 'sound-dai' > property to represent the input audio path. > > Finally, simply connecting to the typec controller node isn't sufficient > because a typec controller can be controlling many usb-c-connectors so I > don't see how the graph binding would be able to figure out how many > usb-c-connectors are connected to a mux like device, unless we took the > approach of this patch. It can follow the endpoint of the typec-switch port (the port parent of the remote end-point would be a 'usb-c-connector'). That is if the graph binding (I'm assuming you mean the switch device here) wants to figure this out in the first place. > Is that why you're proposing this binding? To > avoid describing a graph binding in the usb-c-connector and effectively > "pushing" the port count up to the mux? No, that is not the intention behind this series. The 'usb-c-connector' still needs the graph binding to the `typec-switch`. SBU, HS and SS lanes might have different muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) > > [2] https://www.onsemi.com/pdf/datasheet/fsa4480-d.pdf [3] https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/connector/usb-connector.yaml#L23
On Thu, Jun 23, 2022 at 5:35 PM Prashant Malani <pmalani@chromium.org> wrote: > > On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > Quoting Prashant Malani (2022-06-23 12:08:21) > > > On Thu, Jun 23, 2022 at 11:30 AM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > > > Quoting Prashant Malani (2022-06-22 10:34:30) > > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > new file mode 100644 > > > > > index 000000000000..78b0190c8543 > > > > > --- /dev/null > > > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > @@ -0,0 +1,74 @@ > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > > > +%YAML 1.2 > > [...] > > > > > + ports: > > > > > + $ref: /schemas/graph.yaml#/properties/ports > > > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > > > + > > > > > + properties: > > > > > + port@0: > > > > > + $ref: /schemas/graph.yaml#/properties/port > > > > > + description: Link between the switch and a Type-C connector. > > > > > > > > Is there an update to the usb-c-connector binding to accept this port > > > > connection? > > > > > > Not at this time. I don't think we should enforce that either. > > > (Type-C data-lines could theoretically be routed through intermediate > > > hardware like retimers/repeaters) > > > > I'm mostly wondering if having such a connection to the usb-c-connector, > > or even through some retimer/repeater, would be sufficient to detect how > > many type-c ports are connected to the device. If the type-c pin > > assignments only support two or four lanes for DP then it seems like we > > should describe the two lanes or four lanes as one graph endpoint > > "output" and then have some 'data-lanes' property in case the DP lanes > > are flipped while being sent to the retimer or usb-c-connector. This > > would of course depend on the capability of the device, i.e. if it can > > remap DP lanes or only has 2 lanes of DP, etc. > > > > > > > + - | > > > > > + drm-bridge { > > > > > + usb-switch { > > > > > + compatible = "typec-switch"; > > > > > > > > I still don't understand the subnode design here. usb-switch as a > > > > container node indicates to me that this is a bus, but in earlier rounds > > > > of this series it was stated this isn't a bus. > > > > > > I am not aware of this as a requirement. Can you please point me to the > > > documentation that states this needs to be the case? > > > > I'm not aware of any documentation for the dos and don'ts here. Are > > there any examples in the bindings directory that split up a device into > > subnodes that isn't in bindings/mfd? > > usb-c-connector [3] and its users is an example. > > > I just know from experience that > > any time I try to make a child node of an existing node that I'm > > supposed to be describing a bus, unless I'm adding some sort of > > exception node like a graph binding or an opp table. Typically a node > > corresponds 1:1 with a device in the kernel. I'll defer to Rob for any > > citations. > > > > > > > > > Why doesn't it work to > > > > merge everything inside usb-switch directly into the drm-bridge node? > > > > > > I attempted to explain the rationale in the previous version [1], but > > > using a dedicated sub-node means the driver doesn't haven't to > > > inspect individual ports to determine which of them need switches > > > registered for them. If it sees a `typec-switch`, it registers a > > > mode-switch and/or orientation-switch. IMO it simplifies the hardware > > > device binding too. > > > > How is that any harder than hard-coding that detail into the driver > > about which port and endpoint is possibly connected to the > > usb-c-connector (or retimer)? All of that logic could be behind some API > > that registers a typec-switch based on a graph port number that's passed > > in, ala drm_of_find_panel_or_bridge()'s design. > > If each driver has to do it (and the port specifics vary for each driver), > it becomes an avoidable overhead for each of them. > I prefer hard-coding such details if avoidable. I suppose both approaches Sorry, I meant "I prefer not hard-coding such details..." > require modifications to the binding and the driver code. > > > > > Coming from a DT writer's perspective, I just want to go through the > > list of output pins in the datasheet and match them up to the ports > > binding for this device. If it's a pure DP bridge, where USB hardware > > isn't an input or an output like the ITE chip, then I don't want to have > > to describe a port graph binding for the case when it's connected to a > > dp-connector (see dp-connector.yaml) in the top-level node and then have > > to make an entirely different subnode for the usb-c-connector case with > > a whole other set of graph ports. > > This approach still allows for that, if the driver has any use for it > (AFAICT these drivers don't). > Iff that driver uses it, one can (optionally) route their output > (top-level) ports through the > "typec-switch" sub-node (and onwards as required). > If it's being used in a "pure-DP" configuration, the "typec-switch" just > goes away (the top level ports can be routed as desired by the driver). > (Again, I must reiterate that neither this driver or the anx driver > utilizes this) > > > > > How would I even know which two differential pairs correspond to port0 > > or port1 in this binding in the ITE case? > > Why do we need to know that? It doesn't affect this or the other > driver or hardware's > functioning in a perceivable way. > > > Ideally we make the graph > > binding more strict for devices by enforcing that their graph ports > > exist. Otherwise we're not fully describing the connections between > > devices and our dtb checkers are going to let things through where the > > driver most likely will fail because it can't figure out what to do, > > e.g. display DP on 4 lanes or play some DP lane rerouting games to act > > as a mux. > > How is the current binding enforcing this? The typec-switch binding > as a first step ensures that the DT is connecting the hardware(anx,ite > etc) to something > that at least "claims" to be a Type-C switch. > > > > > > > > > It also maps with the internal block diagram for these hardware > > > components (for ex. the anx7625 crosspoint switch is a separate > > > sub-block within anx7625). > > > > We don't make DT bindings for sub-components like this very often. It > > would make more sense to me to have a subnode if a typec switch was some > > sort of off the shelf hard macro that the hardware engineer placed down > > inside the IC that they delivered. Then we could have a completely > > generic driver that binds to the generic binding that knows how to drive > > the hardware, because it's an unchangeable hard macro with a well > > defined programming interface. > > > > > > > > [1] https://lore.kernel.org/linux-usb/CACeCKaeH6qTTdG_huC4yw0xxG8TYEOtfPW3tiVNwYs=P4QVPXg@mail.gmail.com/ > > > > I looked at the fsa4480 driver and the device has a publicly available > > datasheet[2]. That device is designed for "audio accessory mode" but I > > guess it's being used to simply mux SBU lines? There isn't an upstream > > user of the binding so far, but it also doesn't look like a complete > > binding. I'd expect to see DN_L/R as a graph output connected to the > > usb-c-connector and probably have a usb2.0 input port and a 'sound-dai' > > property to represent the input audio path. > > > > Finally, simply connecting to the typec controller node isn't sufficient > > because a typec controller can be controlling many usb-c-connectors so I > > don't see how the graph binding would be able to figure out how many > > usb-c-connectors are connected to a mux like device, unless we took the > > approach of this patch. > > It can follow the endpoint of the typec-switch port (the port parent > of the remote > end-point would be a 'usb-c-connector'). That is if the graph binding > (I'm assuming you mean the switch device here) wants to figure this > out in the first place. > > > Is that why you're proposing this binding? To > > avoid describing a graph binding in the usb-c-connector and effectively > > "pushing" the port count up to the mux? > > No, that is not the intention behind this series. The > 'usb-c-connector' still needs the > graph binding to the `typec-switch`. SBU, HS and SS lanes might have different > muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) > > > > > [2] https://www.onsemi.com/pdf/datasheet/fsa4480-d.pdf > > [3] https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/connector/usb-connector.yaml#L23
Quoting Prashant Malani (2022-06-23 17:35:38) > On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > I'm not aware of any documentation for the dos and don'ts here. Are > > there any examples in the bindings directory that split up a device into > > subnodes that isn't in bindings/mfd? > > usb-c-connector [3] and its users is an example. What are the subnodes? The graph ports? That is not what I meant. I meant splitting up a device functionality, like type-c and display bridge, into subnodes. Composition of devices through DT bindings isn't how it's done. Instead, we dump all the different functionality into the same node. For example, look at the number of bindings that have both #clock-cells and #reset-cells, when those are distinct frameworks in the kernel and also different properties. We don't make subnodes to contain the different functionality of a device. And in this case I still don't see the point to making a subnode. The API can simply setup a type-c switch based on a graph binding for the toplevel node, e.g. the drm-bridge, and the driver can tell the API which port+endpoint to use to search the graph for the usb-c-connector to associate with the switch. We don't need to connect the graph within the drm-bridge node to the graph within the typec-switch node to do that. That's an internal detail of the drm-bridge that we don't expose to DT, because the driver knows the detail. It also aligns the graph binding for the top-level node with non-typec bindings, like drm, which don't use a second level of graph binding to achieve essentially the same thing when the output is connected to a DP connector. > > > > > > > > > Why doesn't it work to > > > > merge everything inside usb-switch directly into the drm-bridge node? > > > > > > I attempted to explain the rationale in the previous version [1], but > > > using a dedicated sub-node means the driver doesn't haven't to > > > inspect individual ports to determine which of them need switches > > > registered for them. If it sees a `typec-switch`, it registers a > > > mode-switch and/or orientation-switch. IMO it simplifies the hardware > > > device binding too. > > > > How is that any harder than hard-coding that detail into the driver > > about which port and endpoint is possibly connected to the > > usb-c-connector (or retimer)? All of that logic could be behind some API > > that registers a typec-switch based on a graph port number that's passed > > in, ala drm_of_find_panel_or_bridge()'s design. > > If each driver has to do it (and the port specifics vary for each driver), > it becomes an avoidable overhead for each of them. > I prefer hard-coding such details if avoidable. I suppose both approaches > require modifications to the binding and the driver code. Ok, sounds like it is not any harder. > > > > > Coming from a DT writer's perspective, I just want to go through the > > list of output pins in the datasheet and match them up to the ports > > binding for this device. If it's a pure DP bridge, where USB hardware > > isn't an input or an output like the ITE chip, then I don't want to have > > to describe a port graph binding for the case when it's connected to a > > dp-connector (see dp-connector.yaml) in the top-level node and then have > > to make an entirely different subnode for the usb-c-connector case with > > a whole other set of graph ports. > > This approach still allows for that, if the driver has any use for it > (AFAICT these drivers don't). > Iff that driver uses it, one can (optionally) route their output > (top-level) ports through the > "typec-switch" sub-node (and onwards as required). > If it's being used in a "pure-DP" configuration, the "typec-switch" just > goes away (the top level ports can be routed as desired by the driver). > (Again, I must reiterate that neither this driver or the anx driver > utilizes this) > > > > > How would I even know which two differential pairs correspond to port0 > > or port1 in this binding in the ITE case? > > Why do we need to know that? It doesn't affect this or the other > driver or hardware's > functioning in a perceivable way. If the device registers allow control of the DP lane to physical pin mapping, so that DP lane0 and DP lane1 can be swapped logically, then we'll want to know which DP lanes we need to swap by writing some lane remapping register in the device. Sometimes for routing purposes devices support this lane remapping feature so the PCB can route the lines directly to the connector instead of going in circles and destroying the signal integrity. > > > Ideally we make the graph > > binding more strict for devices by enforcing that their graph ports > > exist. Otherwise we're not fully describing the connections between > > devices and our dtb checkers are going to let things through where the > > driver most likely will fail because it can't figure out what to do, > > e.g. display DP on 4 lanes or play some DP lane rerouting games to act > > as a mux. > > How is the current binding enforcing this? The typec-switch binding > as a first step ensures that the DT is connecting the hardware(anx,ite > etc) to something > that at least "claims" to be a Type-C switch. I'm simply saying that we can extend existing bindings like anx or ite to have required properties for ports so that we know the driver will find something on the other end of the graph. A binding that doesn't have any ports will be invalid. I don't know if that's possible to do in the schema. > > > Is that why you're proposing this binding? To > > avoid describing a graph binding in the usb-c-connector and effectively > > "pushing" the port count up to the mux? > > No, that is not the intention behind this series. The > 'usb-c-connector' still needs the > graph binding to the `typec-switch`. SBU, HS and SS lanes might have different > muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) If the usb-c-connector still needs a graph binding to the typec-switch then why isn't that part of this series?
On Thu, Jun 23, 2022 at 7:13 PM Stephen Boyd <swboyd@chromium.org> wrote: > > Quoting Prashant Malani (2022-06-23 17:35:38) > > On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > I'm not aware of any documentation for the dos and don'ts here. Are > > > there any examples in the bindings directory that split up a device into > > > subnodes that isn't in bindings/mfd? > > > > usb-c-connector [3] and its users is an example. > > What are the subnodes? The graph ports? That is not what I meant. cros-ec-typec [4] uses subnodes of usb-c-connector. Chrome OS DTs use the ports from the included usb-c-connector to switching hardware. > I meant splitting up a device functionality, like type-c and display > bridge, into subnodes. Composition of devices through DT bindings isn't > how it's done. Instead, we dump all the different functionality into the > same node. For example, look at the number of bindings that have both > #clock-cells and #reset-cells, when those are distinct frameworks in the > kernel and also different properties. We don't make subnodes to contain > the different functionality of a device. > > And in this case I still don't see the point to making a subnode. I've already provided my best effort at explaining the rationale. > The > API can simply setup a type-c switch based on a graph binding for the > toplevel node, e.g. the drm-bridge, and the driver can tell the API > which port+endpoint to use to search the graph for the usb-c-connector > to associate with the switch. OK, drm-bridge uses that approach. This is another approach. I didn't fully understand why we *have* to follow what drm-bridge is doing. > We don't need to connect the graph within > the drm-bridge node to the graph within the typec-switch node to do > that. That's an internal detail of the drm-bridge that we don't expose > to DT, because the driver knows the detail. I still don't understand why we can't do that. These devices have actual hardware blocks that represent the Type-C switch functionality. > It also aligns the graph > binding for the top-level node with non-typec bindings, like drm, which > don't use a second level of graph binding to achieve essentially the > same thing when the output is connected to a DP connector. > > > > > > > > > > > > > Why doesn't it work to > > > > > merge everything inside usb-switch directly into the drm-bridge node? > > > > > > > > I attempted to explain the rationale in the previous version [1], but > > > > using a dedicated sub-node means the driver doesn't haven't to > > > > inspect individual ports to determine which of them need switches > > > > registered for them. If it sees a `typec-switch`, it registers a > > > > mode-switch and/or orientation-switch. IMO it simplifies the hardware > > > > device binding too. > > > > > > How is that any harder than hard-coding that detail into the driver > > > about which port and endpoint is possibly connected to the > > > usb-c-connector (or retimer)? All of that logic could be behind some API > > > that registers a typec-switch based on a graph port number that's passed > > > in, ala drm_of_find_panel_or_bridge()'s design. > > > > If each driver has to do it (and the port specifics vary for each driver), > > it becomes an avoidable overhead for each of them. > > I prefer hard-coding such details if avoidable. I suppose both approaches > > require modifications to the binding and the driver code. > > Ok, sounds like it is not any harder. I feel this approach is easier :) > > > > > > > > > Coming from a DT writer's perspective, I just want to go through the > > > list of output pins in the datasheet and match them up to the ports > > > binding for this device. If it's a pure DP bridge, where USB hardware > > > isn't an input or an output like the ITE chip, then I don't want to have > > > to describe a port graph binding for the case when it's connected to a > > > dp-connector (see dp-connector.yaml) in the top-level node and then have > > > to make an entirely different subnode for the usb-c-connector case with > > > a whole other set of graph ports. > > > > This approach still allows for that, if the driver has any use for it > > (AFAICT these drivers don't). > > Iff that driver uses it, one can (optionally) route their output > > (top-level) ports through the > > "typec-switch" sub-node (and onwards as required). > > If it's being used in a "pure-DP" configuration, the "typec-switch" just > > goes away (the top level ports can be routed as desired by the driver). > > (Again, I must reiterate that neither this driver or the anx driver > > utilizes this) > > > > > > > > How would I even know which two differential pairs correspond to port0 > > > or port1 in this binding in the ITE case? > > > > Why do we need to know that? It doesn't affect this or the other > > driver or hardware's > > functioning in a perceivable way. > > If the device registers allow control of the DP lane to physical pin > mapping, so that DP lane0 and DP lane1 can be swapped logically, then > we'll want to know which DP lanes we need to swap by writing some lane > remapping register in the device. Sometimes for routing purposes devices > support this lane remapping feature so the PCB can route the lines > directly to the connector instead of going in circles and destroying the > signal integrity. Then add more end-points to port@1 (for each differential pair you want to describe) of the usb-c-connector and route them to the typec-switch accordingly. FWIW I'm not aware of h/w *that supports DP alt mode* that uses the functionality you're referring to. > > > > > > Ideally we make the graph > > > binding more strict for devices by enforcing that their graph ports > > > exist. Otherwise we're not fully describing the connections between > > > devices and our dtb checkers are going to let things through where the > > > driver most likely will fail because it can't figure out what to do, > > > e.g. display DP on 4 lanes or play some DP lane rerouting games to act > > > as a mux. > > > > How is the current binding enforcing this? The typec-switch binding > > as a first step ensures that the DT is connecting the hardware(anx,ite > > etc) to something > > that at least "claims" to be a Type-C switch. > > I'm simply saying that we can extend existing bindings like anx or ite > to have required properties for ports so that we know the driver will > find something on the other end of the graph. A binding that doesn't > have any ports will be invalid. typec-switch requires a port. I don't know if that's possible to do > in the schema. > > > > > > Is that why you're proposing this binding? To > > > avoid describing a graph binding in the usb-c-connector and effectively > > > "pushing" the port count up to the mux? > > > > No, that is not the intention behind this series. The > > 'usb-c-connector' still needs the > > graph binding to the `typec-switch`. SBU, HS and SS lanes might have different > > muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) > > If the usb-c-connector still needs a graph binding to the typec-switch > then why isn't that part of this series? That's not what I meant (what I meant earlier is the intention is not what you stated). I simply meant that the usb-c-connectors ports should be connected to the typec-switch ports. There isn't any binding update required for this. [4] https://www.kernel.org/doc/Documentation/devicetree/bindings/chrome/google%2Ccros-ec-typec.yaml
Quoting Prashant Malani (2022-06-23 19:48:04) > On Thu, Jun 23, 2022 at 7:13 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > Quoting Prashant Malani (2022-06-23 17:35:38) > > > On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > > > I'm not aware of any documentation for the dos and don'ts here. Are > > > > there any examples in the bindings directory that split up a device into > > > > subnodes that isn't in bindings/mfd? > > > > > > usb-c-connector [3] and its users is an example. > > > > What are the subnodes? The graph ports? That is not what I meant. > > cros-ec-typec [4] uses subnodes of usb-c-connector. Chrome OS DTs > use the ports from the included usb-c-connector to switching hardware. Ok, got it. usb-c-connector nodes are children of the typec controller (in this case cros-ec-typec) because otherwise we would need to make a phandle link from the usb-c-connector node(s) under the root node / to the typec controller. The phandle link may need to be done in both directions, so it makes more sense to put the usb-c-connector nodes underneath the typec controller to express the direct relationship between the typec controller and the usb-c-connectors. Furthermore, the usb-c-connector is not integrated as part of the EC in the same package. There is a discrete part placed on the board that corresponds to the usb-c-connector and that is separate from the EC. The connectors are in essence only controllable through the EC because that's the typec controller. It's similar to how we place i2c devices as child nodes of the i2c controller. > > > I meant splitting up a device functionality, like type-c and display > > bridge, into subnodes. Composition of devices through DT bindings isn't > > how it's done. Instead, we dump all the different functionality into the > > same node. For example, look at the number of bindings that have both > > #clock-cells and #reset-cells, when those are distinct frameworks in the > > kernel and also different properties. We don't make subnodes to contain > > the different functionality of a device. > > > > And in this case I still don't see the point to making a subnode. > > I've already provided my best effort at explaining the rationale. > > > The > > API can simply setup a type-c switch based on a graph binding for the > > toplevel node, e.g. the drm-bridge, and the driver can tell the API > > which port+endpoint to use to search the graph for the usb-c-connector > > to associate with the switch. > > OK, drm-bridge uses that approach. This is another approach. I didn't fully > understand why we *have* to follow what drm-bridge is doing. > > > We don't need to connect the graph within > > the drm-bridge node to the graph within the typec-switch node to do > > that. That's an internal detail of the drm-bridge that we don't expose > > to DT, because the driver knows the detail. > > I still don't understand why we can't do that. These devices have actual > hardware blocks that represent the Type-C switch functionality. > We don't break up device functionality for an IC into different subnodes with different compatibles. Similarly, we don't describe internal connection details of device nodes. The device driver that binds to the compatible should know the details of the internal block diagram of the part. The DT binding should describe the external connections of the part and have properties that inform the driver about how the part was integrated into the system (e.g. mode-switch). The unwritten DT mantra is "less is more". We could definitely make many subnodes and add properties for everything inside an IC so that the DT describes the complete block diagram of the part, but at that point the driver is a shell of its former self. The driver will spend time parsing properties to learn details that are entirely unchanging for the lifetime of the device (e.g. that the device has typec switch capabilities); things that should be hard-coded in the driver. Of course, if the device is integrated into the system and doesn't need to perform typec switching, then we want a property to tell the driver that this device is integrated in a way that the typec switch is not needed/used. Basically the driver should key that functionality off of the presence of the 'mode-switch' or 'orientation-switch' property instead of off the presence of a typec-switch subnode. > > > > > > > > > > > How would I even know which two differential pairs correspond to port0 > > > > or port1 in this binding in the ITE case? > > > > > > Why do we need to know that? It doesn't affect this or the other > > > driver or hardware's > > > functioning in a perceivable way. > > > > If the device registers allow control of the DP lane to physical pin > > mapping, so that DP lane0 and DP lane1 can be swapped logically, then > > we'll want to know which DP lanes we need to swap by writing some lane > > remapping register in the device. Sometimes for routing purposes devices > > support this lane remapping feature so the PCB can route the lines > > directly to the connector instead of going in circles and destroying the > > signal integrity. > > Then add more end-points to port@1 (for each differential pair > you want to describe) of the usb-c-connector and route them > to the typec-switch accordingly. > FWIW I'm not aware of h/w *that supports DP alt mode* that uses the > functionality > you're referring to. > The Qualcomm QMP usb+dp phy supports lane remapping. > > > > > > > > > Is that why you're proposing this binding? To > > > > avoid describing a graph binding in the usb-c-connector and effectively > > > > "pushing" the port count up to the mux? > > > > > > No, that is not the intention behind this series. The > > > 'usb-c-connector' still needs the > > > graph binding to the `typec-switch`. SBU, HS and SS lanes might have different > > > muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) > > > > If the usb-c-connector still needs a graph binding to the typec-switch > > then why isn't that part of this series? > > That's not what I meant (what I meant earlier is the intention is not > what you stated). > I simply meant that the usb-c-connectors ports should be connected to > the typec-switch > ports. There isn't any binding update required for this. > Ok. Got it.
On Fri, Jun 24, 2022 at 12:50 PM Stephen Boyd <swboyd@chromium.org> wrote: > > Quoting Prashant Malani (2022-06-23 19:48:04) > > On Thu, Jun 23, 2022 at 7:13 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > Quoting Prashant Malani (2022-06-23 17:35:38) > > > > On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > > > > > I'm not aware of any documentation for the dos and don'ts here. Are > > > > > there any examples in the bindings directory that split up a device into > > > > > subnodes that isn't in bindings/mfd? > > > > > > > > usb-c-connector [3] and its users is an example. > > > > > > What are the subnodes? The graph ports? That is not what I meant. > > > > cros-ec-typec [4] uses subnodes of usb-c-connector. Chrome OS DTs > > use the ports from the included usb-c-connector to switching hardware. > > Ok, got it. usb-c-connector nodes are children of the typec controller > (in this case cros-ec-typec) because otherwise we would need to make a > phandle link from the usb-c-connector node(s) under the root node / to > the typec controller. The phandle link may need to be done in both > directions, so it makes more sense to put the usb-c-connector nodes > underneath the typec controller to express the direct relationship > between the typec controller and the usb-c-connectors. > > Furthermore, the usb-c-connector is not integrated as part of the EC in > the same package. There is a discrete part placed on the board that > corresponds to the usb-c-connector and that is separate from the EC. The > connectors are in essence only controllable through the EC because > that's the typec controller. From the perspective of the AP, the `usb-c-connector` *is* an integrated part of the Chrome EC; there is no alternative way to control it except through the Chrome EC. So the above example reinforces the usage model for typec-switch (which is also an "integrated" component). > It's similar to how we place i2c devices as > child nodes of the i2c controller. > > > > > > I meant splitting up a device functionality, like type-c and display > > > bridge, into subnodes. Composition of devices through DT bindings isn't > > > how it's done. Instead, we dump all the different functionality into the > > > same node. For example, look at the number of bindings that have both > > > #clock-cells and #reset-cells, when those are distinct frameworks in the > > > kernel and also different properties. We don't make subnodes to contain > > > the different functionality of a device. > > > > > > And in this case I still don't see the point to making a subnode. > > > > I've already provided my best effort at explaining the rationale. > > > > > The > > > API can simply setup a type-c switch based on a graph binding for the > > > toplevel node, e.g. the drm-bridge, and the driver can tell the API > > > which port+endpoint to use to search the graph for the usb-c-connector > > > to associate with the switch. > > > > OK, drm-bridge uses that approach. This is another approach. I didn't fully > > understand why we *have* to follow what drm-bridge is doing. > > > > > We don't need to connect the graph within > > > the drm-bridge node to the graph within the typec-switch node to do > > > that. That's an internal detail of the drm-bridge that we don't expose > > > to DT, because the driver knows the detail. > > > > I still don't understand why we can't do that. These devices have actual > > hardware blocks that represent the Type-C switch functionality. > > > > We don't break up device functionality for an IC into different subnodes > with different compatibles. Similarly, we don't describe internal > connection details of device nodes. The device driver that binds to the > compatible should know the details of the internal block diagram of the > part. I don't completely agree with the above. There is scope for middle-ground where some details can be codified into DT bindings, and the driver can have the flexibility to be able to handle them. But this now devolves into an ideological debate which I don't want to get involved in, so I will restrict my responses on this subject. > The DT binding should describe the external connections of the > part and have properties that inform the driver about how the part was > integrated into the system (e.g. mode-switch). The unwritten DT mantra > is "less is more". > > We could definitely make many subnodes and add properties for everything > inside an IC so that the DT describes the complete block diagram of the > part, but at that point the driver is a shell of its former self. That is a pathological/extreme argument which is not the case here, we're just adding 1 sub-node because it's a sub-component that interfaces with a kernel framework (Type-C class etc). The driver should be able to deal with varying hardware configurations for the device and I don't believe that makes it a "shell of its former self" any more than hard-coding port details in the driver. > The driver will spend time parsing properties to learn details that are This parsing only occurs 1 once at probe, so I don't consider it much of an overhead. The alternative suggested leads to the driver using time looking up OF ports (with the port number). I fail to see how either is noticeably more efficient than the other, especially on modern systems. > entirely unchanging for the lifetime of the device (e.g. that the device > has typec switch capabilities); things that should be hard-coded in the > driver. > > Of course, if the device is integrated into the system and doesn't need > to perform typec switching, then we want a property to tell the driver > that this device is integrated in a way that the typec switch is not > needed/used. Basically the driver should key that functionality off of > the presence of the 'mode-switch' or 'orientation-switch' property > instead of off the presence of a typec-switch subnode. > > > > > > > > > > > > > > > How would I even know which two differential pairs correspond to port0 > > > > > or port1 in this binding in the ITE case? > > > > > > > > Why do we need to know that? It doesn't affect this or the other > > > > driver or hardware's > > > > functioning in a perceivable way. > > > > > > If the device registers allow control of the DP lane to physical pin > > > mapping, so that DP lane0 and DP lane1 can be swapped logically, then > > > we'll want to know which DP lanes we need to swap by writing some lane > > > remapping register in the device. Sometimes for routing purposes devices > > > support this lane remapping feature so the PCB can route the lines > > > directly to the connector instead of going in circles and destroying the > > > signal integrity. > > > > Then add more end-points to port@1 (for each differential pair > > you want to describe) of the usb-c-connector and route them > > to the typec-switch accordingly. > > FWIW I'm not aware of h/w *that supports DP alt mode* that uses the > > functionality > > you're referring to. > > > > The Qualcomm QMP usb+dp phy supports lane remapping. Ok great. So we can follow the method described above for specifying these differential pairs if required. That is not related to this patch series (although it is compatible with it). > > > > > > > > > > > > > Is that why you're proposing this binding? To > > > > > avoid describing a graph binding in the usb-c-connector and effectively > > > > > "pushing" the port count up to the mux? > > > > > > > > No, that is not the intention behind this series. The > > > > 'usb-c-connector' still needs the > > > > graph binding to the `typec-switch`. SBU, HS and SS lanes might have different > > > > muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) > > > > > > If the usb-c-connector still needs a graph binding to the typec-switch > > > then why isn't that part of this series? > > > > That's not what I meant (what I meant earlier is the intention is not > > what you stated). > > I simply meant that the usb-c-connectors ports should be connected to > > the typec-switch > > ports. There isn't any binding update required for this. > > > > Ok. Got it. This really is a limited binding change that helps describe connections between Type-C components, helps these components integrate with the kernel Type-C framework, and consolidates the associated properties. I believe it works for most current use cases in the upstream kernel. I'm happy to discuss more theoretical use cases further, but respectfully, I prefer to do so off-list. If the maintainer is OK with it (Krzysztof has reviewed it, but I don't want to presume what the protocol is for patches in this subsystem), and we've provided 2 users as asked for in v4 [5], then I request its consideration for submission. If the maintainers have further concerns, we'd be happy to address them. Best regards, -Prashant [5] https://lore.kernel.org/linux-usb/20220616193424.GA3844759-robh@kernel.org/
Quoting Prashant Malani (2022-06-24 14:41:36) > On Fri, Jun 24, 2022 at 12:50 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > Quoting Prashant Malani (2022-06-23 19:48:04) > > > On Thu, Jun 23, 2022 at 7:13 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > > > Quoting Prashant Malani (2022-06-23 17:35:38) > > > > > On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > > > > > > > I'm not aware of any documentation for the dos and don'ts here. Are > > > > > > there any examples in the bindings directory that split up a device into > > > > > > subnodes that isn't in bindings/mfd? > > > > > > > > > > usb-c-connector [3] and its users is an example. > > > > > > > > What are the subnodes? The graph ports? That is not what I meant. > > > > > > cros-ec-typec [4] uses subnodes of usb-c-connector. Chrome OS DTs > > > use the ports from the included usb-c-connector to switching hardware. > > > > Ok, got it. usb-c-connector nodes are children of the typec controller > > (in this case cros-ec-typec) because otherwise we would need to make a > > phandle link from the usb-c-connector node(s) under the root node / to > > the typec controller. The phandle link may need to be done in both > > directions, so it makes more sense to put the usb-c-connector nodes > > underneath the typec controller to express the direct relationship > > between the typec controller and the usb-c-connectors. > > > > Furthermore, the usb-c-connector is not integrated as part of the EC in > > the same package. There is a discrete part placed on the board that > > corresponds to the usb-c-connector and that is separate from the EC. The > > connectors are in essence only controllable through the EC because > > that's the typec controller. > > From the perspective of the AP, the `usb-c-connector` *is* an integrated part of > the Chrome EC; there is no alternative way to control it except > through the Chrome EC. > So the above example reinforces the usage model for typec-switch (which is > also an "integrated" component). No the usb-c-connector is not an integrated part of the EC. It is a discrete part with a part number that gets placed on the PCB. From the perspective of the AP it is controlled via the EC, but it is not integrated into the same package that the EC is packaged in to be soldered down to the PCB. So the example of usb-c-connector as a subnode doesn't reinforce the argument for a typec-switch binding. It highlights the difference that I've been trying to explain. The difference between internal vs. external components of a device. In the EC case the usb-c-connector is an external component from the EC, hence the two nodes. In the anx or ite case the typec switch is an internal component, hence the single node for the anx or ite part. > > This really is a limited binding change that helps describe connections > between Type-C components, helps these components integrate with > the kernel Type-C framework, and consolidates the associated properties. > I believe it works for most current use cases in the upstream kernel. > > I'm happy to discuss more theoretical use cases further, but > respectfully, I prefer to do > so off-list. I'm happy to move the discussion to the anx or ite bindings if you'd prefer to discuss more concrete bindings. > > If the maintainer is OK with it (Krzysztof has reviewed it, but I > don't want to presume > what the protocol is for patches in this subsystem), and we've > provided 2 users as asked for > in v4 [5], then I request its consideration for submission. > If the maintainers have further concerns, we'd be happy to address them. > Rob?
On 24/06/2022 23:41, Prashant Malani wrote: > On Fri, Jun 24, 2022 at 12:50 PM Stephen Boyd <swboyd@chromium.org> wrote: >> >> Quoting Prashant Malani (2022-06-23 19:48:04) >>> On Thu, Jun 23, 2022 at 7:13 PM Stephen Boyd <swboyd@chromium.org> wrote: >>>> >>>> Quoting Prashant Malani (2022-06-23 17:35:38) >>>>> On Thu, Jun 23, 2022 at 4:14 PM Stephen Boyd <swboyd@chromium.org> wrote: >>>>>> >>>>>> I'm not aware of any documentation for the dos and don'ts here. Are >>>>>> there any examples in the bindings directory that split up a device into >>>>>> subnodes that isn't in bindings/mfd? >>>>> >>>>> usb-c-connector [3] and its users is an example. >>>> >>>> What are the subnodes? The graph ports? That is not what I meant. >>> >>> cros-ec-typec [4] uses subnodes of usb-c-connector. Chrome OS DTs >>> use the ports from the included usb-c-connector to switching hardware. >> >> Ok, got it. usb-c-connector nodes are children of the typec controller >> (in this case cros-ec-typec) because otherwise we would need to make a >> phandle link from the usb-c-connector node(s) under the root node / to >> the typec controller. The phandle link may need to be done in both >> directions, so it makes more sense to put the usb-c-connector nodes >> underneath the typec controller to express the direct relationship >> between the typec controller and the usb-c-connectors. >> >> Furthermore, the usb-c-connector is not integrated as part of the EC in >> the same package. There is a discrete part placed on the board that >> corresponds to the usb-c-connector and that is separate from the EC. The >> connectors are in essence only controllable through the EC because >> that's the typec controller. > > From the perspective of the AP, the `usb-c-connector` *is* an integrated part of > the Chrome EC; there is no alternative way to control it except > through the Chrome EC. > So the above example reinforces the usage model for typec-switch (which is > also an "integrated" component). > >> It's similar to how we place i2c devices as >> child nodes of the i2c controller. >> >>> >>>> I meant splitting up a device functionality, like type-c and display >>>> bridge, into subnodes. Composition of devices through DT bindings isn't >>>> how it's done. Instead, we dump all the different functionality into the >>>> same node. For example, look at the number of bindings that have both >>>> #clock-cells and #reset-cells, when those are distinct frameworks in the >>>> kernel and also different properties. We don't make subnodes to contain >>>> the different functionality of a device. >>>> >>>> And in this case I still don't see the point to making a subnode. >>> >>> I've already provided my best effort at explaining the rationale. >>> >>>> The >>>> API can simply setup a type-c switch based on a graph binding for the >>>> toplevel node, e.g. the drm-bridge, and the driver can tell the API >>>> which port+endpoint to use to search the graph for the usb-c-connector >>>> to associate with the switch. >>> >>> OK, drm-bridge uses that approach. This is another approach. I didn't fully >>> understand why we *have* to follow what drm-bridge is doing. >>> >>>> We don't need to connect the graph within >>>> the drm-bridge node to the graph within the typec-switch node to do >>>> that. That's an internal detail of the drm-bridge that we don't expose >>>> to DT, because the driver knows the detail. >>> >>> I still don't understand why we can't do that. These devices have actual >>> hardware blocks that represent the Type-C switch functionality. >>> >> >> We don't break up device functionality for an IC into different subnodes >> with different compatibles. Similarly, we don't describe internal >> connection details of device nodes. The device driver that binds to the >> compatible should know the details of the internal block diagram of the >> part. > > I don't completely agree with the above. There > is scope for middle-ground where some details can be codified into > DT bindings, and the driver can have the flexibility to be able to handle them. > But this now devolves into an ideological debate which I don't want > to get involved in, so I will restrict my responses on this subject. > >> The DT binding should describe the external connections of the >> part and have properties that inform the driver about how the part was >> integrated into the system (e.g. mode-switch). The unwritten DT mantra >> is "less is more". >> >> We could definitely make many subnodes and add properties for everything >> inside an IC so that the DT describes the complete block diagram of the >> part, but at that point the driver is a shell of its former self. > > That is a pathological/extreme argument which is not the case here, > we're just adding 1 sub-node because it's a sub-component that interfaces > with a kernel framework (Type-C class etc). The driver should be able to deal > with varying hardware configurations for the device and I don't believe that > makes it a "shell of its former self" any more than hard-coding port > details in the driver. > >> The driver will spend time parsing properties to learn details that are > > This parsing only occurs 1 once at probe, so I don't consider it much > of an overhead. The alternative suggested leads to the driver using time > looking up OF ports (with the port number). I fail to see how either is > noticeably more efficient than the other, especially on modern systems. > >> entirely unchanging for the lifetime of the device (e.g. that the device >> has typec switch capabilities); things that should be hard-coded in the >> driver. >> >> Of course, if the device is integrated into the system and doesn't need >> to perform typec switching, then we want a property to tell the driver >> that this device is integrated in a way that the typec switch is not >> needed/used. Basically the driver should key that functionality off of >> the presence of the 'mode-switch' or 'orientation-switch' property >> instead of off the presence of a typec-switch subnode. >> >>>>> >>>>>> >>>>>> How would I even know which two differential pairs correspond to port0 >>>>>> or port1 in this binding in the ITE case? >>>>> >>>>> Why do we need to know that? It doesn't affect this or the other >>>>> driver or hardware's >>>>> functioning in a perceivable way. >>>> >>>> If the device registers allow control of the DP lane to physical pin >>>> mapping, so that DP lane0 and DP lane1 can be swapped logically, then >>>> we'll want to know which DP lanes we need to swap by writing some lane >>>> remapping register in the device. Sometimes for routing purposes devices >>>> support this lane remapping feature so the PCB can route the lines >>>> directly to the connector instead of going in circles and destroying the >>>> signal integrity. >>> >>> Then add more end-points to port@1 (for each differential pair >>> you want to describe) of the usb-c-connector and route them >>> to the typec-switch accordingly. >>> FWIW I'm not aware of h/w *that supports DP alt mode* that uses the >>> functionality >>> you're referring to. >>> >> >> The Qualcomm QMP usb+dp phy supports lane remapping. > > Ok great. So we can follow the method described above for specifying these > differential pairs if required. That is not related to this patch > series (although it is compatible > with it). > >> >>>> >>>>> >>>>>> Is that why you're proposing this binding? To >>>>>> avoid describing a graph binding in the usb-c-connector and effectively >>>>>> "pushing" the port count up to the mux? >>>>> >>>>> No, that is not the intention behind this series. The >>>>> 'usb-c-connector' still needs the >>>>> graph binding to the `typec-switch`. SBU, HS and SS lanes might have different >>>>> muxes altogether (usb-c-connect has separate ports for SBU, HS and SS lanes) >>>> >>>> If the usb-c-connector still needs a graph binding to the typec-switch >>>> then why isn't that part of this series? >>> >>> That's not what I meant (what I meant earlier is the intention is not >>> what you stated). >>> I simply meant that the usb-c-connectors ports should be connected to >>> the typec-switch >>> ports. There isn't any binding update required for this. >>> >> >> Ok. Got it. > > This really is a limited binding change that helps describe connections > between Type-C components, helps these components integrate with > the kernel Type-C framework, and consolidates the associated properties. > I believe it works for most current use cases in the upstream kernel. > > I'm happy to discuss more theoretical use cases further, but > respectfully, I prefer to do > so off-list. > > If the maintainer is OK with it (Krzysztof has reviewed it, but I > don't want to presume > what the protocol is for patches in this subsystem), and we've > provided 2 users as asked for Although I reviewed it, but Stephen has legitimate concerns and they should be addressed. I guess Rob's feedback would be valuable here as well. I think it would help if you articulated the exact problem, because there is a quite a discussion. Do I understand correctly that the bindings mimic USB connector and this is not appropriate for this type of a device? Or maybe this should not be represented in DT at all? > in v4 [5], then I request its consideration for submission. > If the maintainers have further concerns, we'd be happy to address them. > > Best regards, > > -Prashant > > [5] https://lore.kernel.org/linux-usb/20220616193424.GA3844759-robh@kernel.org/ Best regards, Krzysztof
On Wed, Jun 22, 2022 at 05:34:30PM +0000, Prashant Malani wrote: > Introduce a binding which represents a component that can control the > routing of USB Type-C data lines as well as address data line > orientation (based on CC lines' orientation). > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > Signed-off-by: Prashant Malani <pmalani@chromium.org> > --- > > Changes since v4: > - Added Reviewed-by tags. > - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were > applied to usb-next) > > Changes since v3: > - No changes. > > Changes since v2: > - Added Reviewed-by and Tested-by tags. > > Changes since v1: > - Removed "items" from compatible. > - Fixed indentation in example. > > .../devicetree/bindings/usb/typec-switch.yaml | 74 +++++++++++++++++++ > 1 file changed, 74 insertions(+) > create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > new file mode 100644 > index 000000000000..78b0190c8543 > --- /dev/null > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > @@ -0,0 +1,74 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: USB Type-C Switch > + > +maintainers: > + - Prashant Malani <pmalani@chromium.org> > + > +description: > + A USB Type-C switch represents a component which routes USB Type-C data > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > + and cable are operating in. It can also modify lane routing based on > + the orientation of a connected Type-C peripheral. > + > +properties: > + compatible: > + const: typec-switch > + > + mode-switch: > + type: boolean > + description: Specify that this switch can handle alternate mode switching. > + > + orientation-switch: > + type: boolean > + description: Specify that this switch can handle orientation switching. > + > + ports: > + $ref: /schemas/graph.yaml#/properties/ports > + description: OF graph binding modelling data lines to the Type-C switch. > + > + properties: > + port@0: > + $ref: /schemas/graph.yaml#/properties/port > + description: Link between the switch and a Type-C connector. > + > + required: > + - port@0 > + > +required: > + - compatible > + - ports > + > +anyOf: > + - required: > + - mode-switch > + - required: > + - orientation-switch > + > +additionalProperties: true > + > +examples: > + - | > + drm-bridge { > + usb-switch { > + compatible = "typec-switch"; Unless this child is supposed to represent what the parent output is connected to, this is just wrong as, at least for the it6505 chip, it doesn't know anything about Type-C functionality. The bridge is just a protocol converter AFAICT. If the child node represents what the output is connected to (like a bus), then yes that is a pattern we have used. For example, a panel represented as child node of a display controller. However, that only works for simple cases, and is a pattern we have gotten away from in favor of using the graph binding. I think Stephen and I are pretty much saying the same thing. Rob
Hello Rob, On Mon, Jun 27, 2022 at 2:04 PM Rob Herring <robh@kernel.org> wrote: > > On Wed, Jun 22, 2022 at 05:34:30PM +0000, Prashant Malani wrote: > > Introduce a binding which represents a component that can control the > > routing of USB Type-C data lines as well as address data line > > orientation (based on CC lines' orientation). > > > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > Signed-off-by: Prashant Malani <pmalani@chromium.org> > > --- > > > > Changes since v4: > > - Added Reviewed-by tags. > > - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were > > applied to usb-next) > > > > Changes since v3: > > - No changes. > > > > Changes since v2: > > - Added Reviewed-by and Tested-by tags. > > > > Changes since v1: > > - Removed "items" from compatible. > > - Fixed indentation in example. > > > > .../devicetree/bindings/usb/typec-switch.yaml | 74 +++++++++++++++++++ > > 1 file changed, 74 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > new file mode 100644 > > index 000000000000..78b0190c8543 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > @@ -0,0 +1,74 @@ > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: USB Type-C Switch > > + > > +maintainers: > > + - Prashant Malani <pmalani@chromium.org> > > + > > +description: > > + A USB Type-C switch represents a component which routes USB Type-C data > > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > > + and cable are operating in. It can also modify lane routing based on > > + the orientation of a connected Type-C peripheral. > > + > > +properties: > > + compatible: > > + const: typec-switch > > + > > + mode-switch: > > + type: boolean > > + description: Specify that this switch can handle alternate mode switching. > > + > > + orientation-switch: > > + type: boolean > > + description: Specify that this switch can handle orientation switching. > > + > > + ports: > > + $ref: /schemas/graph.yaml#/properties/ports > > + description: OF graph binding modelling data lines to the Type-C switch. > > + > > + properties: > > + port@0: > > + $ref: /schemas/graph.yaml#/properties/port > > + description: Link between the switch and a Type-C connector. > > + > > + required: > > + - port@0 > > + > > +required: > > + - compatible > > + - ports > > + > > +anyOf: > > + - required: > > + - mode-switch > > + - required: > > + - orientation-switch > > + > > +additionalProperties: true > > + > > +examples: > > + - | > > + drm-bridge { > > + usb-switch { > > + compatible = "typec-switch"; > > Unless this child is supposed to represent what the parent output is > connected to, this is just wrong as, at least for the it6505 chip, it > doesn't know anything about Type-C functionality. The bridge is > just a protocol converter AFAICT. I'll let Pin-Yen comment on the specifics of the it6505 chip. > > If the child node represents what the output is connected to (like a > bus), then yes that is a pattern we have used. For the anx7625 case, the child node does represent what the output is connected to (the usb-c-connector via the switch). Does that not qualify? Or do you mean the child node should be a usb-c-connector itself? > For example, a panel > represented as child node of a display controller. However, that only > works for simple cases, and is a pattern we have gotten away from in > favor of using the graph binding. The child node will still use a OF graph binding to connect to the usb-c-connector. Is that insufficient to consider a child node usage here? By "using the graph binding", do you mean "only use the top-level ports" ? I'm trying to clarify this, so that it will inform future versions and patches. > > I think Stephen and I are pretty much saying the same thing. > > Rob
On Mon, Jun 27, 2022 at 02:43:39PM -0700, Prashant Malani wrote: > Hello Rob, > > On Mon, Jun 27, 2022 at 2:04 PM Rob Herring <robh@kernel.org> wrote: > > > > On Wed, Jun 22, 2022 at 05:34:30PM +0000, Prashant Malani wrote: > > > Introduce a binding which represents a component that can control the > > > routing of USB Type-C data lines as well as address data line > > > orientation (based on CC lines' orientation). > > > > > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > > > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > > > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > Signed-off-by: Prashant Malani <pmalani@chromium.org> > > > --- > > > > > > Changes since v4: > > > - Added Reviewed-by tags. > > > - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were > > > applied to usb-next) > > > > > > Changes since v3: > > > - No changes. > > > > > > Changes since v2: > > > - Added Reviewed-by and Tested-by tags. > > > > > > Changes since v1: > > > - Removed "items" from compatible. > > > - Fixed indentation in example. > > > > > > .../devicetree/bindings/usb/typec-switch.yaml | 74 +++++++++++++++++++ > > > 1 file changed, 74 insertions(+) > > > create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > new file mode 100644 > > > index 000000000000..78b0190c8543 > > > --- /dev/null > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > @@ -0,0 +1,74 @@ > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > +%YAML 1.2 > > > +--- > > > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > + > > > +title: USB Type-C Switch > > > + > > > +maintainers: > > > + - Prashant Malani <pmalani@chromium.org> > > > + > > > +description: > > > + A USB Type-C switch represents a component which routes USB Type-C data > > > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > > > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > > > + and cable are operating in. It can also modify lane routing based on > > > + the orientation of a connected Type-C peripheral. > > > + > > > +properties: > > > + compatible: > > > + const: typec-switch > > > + > > > + mode-switch: > > > + type: boolean > > > + description: Specify that this switch can handle alternate mode switching. > > > + > > > + orientation-switch: > > > + type: boolean > > > + description: Specify that this switch can handle orientation switching. > > > + > > > + ports: > > > + $ref: /schemas/graph.yaml#/properties/ports > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > + > > > + properties: > > > + port@0: > > > + $ref: /schemas/graph.yaml#/properties/port > > > + description: Link between the switch and a Type-C connector. > > > + > > > + required: > > > + - port@0 > > > + > > > +required: > > > + - compatible > > > + - ports > > > + > > > +anyOf: > > > + - required: > > > + - mode-switch > > > + - required: > > > + - orientation-switch > > > + > > > +additionalProperties: true > > > + > > > +examples: > > > + - | > > > + drm-bridge { > > > + usb-switch { > > > + compatible = "typec-switch"; > > > > Unless this child is supposed to represent what the parent output is > > connected to, this is just wrong as, at least for the it6505 chip, it > > doesn't know anything about Type-C functionality. The bridge is > > just a protocol converter AFAICT. > > I'll let Pin-Yen comment on the specifics of the it6505 chip. We're all waiting... > > If the child node represents what the output is connected to (like a > > bus), then yes that is a pattern we have used. > > For the anx7625 case, the child node does represent what the output is connected > to (the usb-c-connector via the switch). Does that not qualify? Or do you mean > the child node should be a usb-c-connector itself? > > > For example, a panel > > represented as child node of a display controller. However, that only > > works for simple cases, and is a pattern we have gotten away from in > > favor of using the graph binding. > > The child node will still use a OF graph binding to connect to the > usb-c-connector. > Is that insufficient to consider a child node usage here? > By "using the graph binding", do you mean "only use the top-level ports" ? > I'm trying to clarify this, so that it will inform future versions and patches. What I want to see is block diagrams of possible h/w with different scenarios and then what the binding looks like in those cases. The switching/muxing could be in the SoC, a bridge chip, a Type C controller, a standalone mux chip, or ????. If you want a somewhat genericish binding, then you need to consider all of these. I don't really have the b/w to work thru all this (and switch/mux is just one part of dealing with Type-C). This is just one of about a hundred patches I get to review a week. Rob
On Wed, Jun 29, 2022 at 2:23 AM Rob Herring <robh@kernel.org> wrote: > > On Mon, Jun 27, 2022 at 02:43:39PM -0700, Prashant Malani wrote: > > Hello Rob, > > > > On Mon, Jun 27, 2022 at 2:04 PM Rob Herring <robh@kernel.org> wrote: > > > > > > On Wed, Jun 22, 2022 at 05:34:30PM +0000, Prashant Malani wrote: > > > > Introduce a binding which represents a component that can control the > > > > routing of USB Type-C data lines as well as address data line > > > > orientation (based on CC lines' orientation). > > > > > > > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > > > > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > > > > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > > Signed-off-by: Prashant Malani <pmalani@chromium.org> > > > > --- > > > > > > > > Changes since v4: > > > > - Added Reviewed-by tags. > > > > - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were > > > > applied to usb-next) > > > > > > > > Changes since v3: > > > > - No changes. > > > > > > > > Changes since v2: > > > > - Added Reviewed-by and Tested-by tags. > > > > > > > > Changes since v1: > > > > - Removed "items" from compatible. > > > > - Fixed indentation in example. > > > > > > > > .../devicetree/bindings/usb/typec-switch.yaml | 74 +++++++++++++++++++ > > > > 1 file changed, 74 insertions(+) > > > > create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > new file mode 100644 > > > > index 000000000000..78b0190c8543 > > > > --- /dev/null > > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > @@ -0,0 +1,74 @@ > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > > +%YAML 1.2 > > > > +--- > > > > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > + > > > > +title: USB Type-C Switch > > > > + > > > > +maintainers: > > > > + - Prashant Malani <pmalani@chromium.org> > > > > + > > > > +description: > > > > + A USB Type-C switch represents a component which routes USB Type-C data > > > > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > > > > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > > > > + and cable are operating in. It can also modify lane routing based on > > > > + the orientation of a connected Type-C peripheral. > > > > + > > > > +properties: > > > > + compatible: > > > > + const: typec-switch > > > > + > > > > + mode-switch: > > > > + type: boolean > > > > + description: Specify that this switch can handle alternate mode switching. > > > > + > > > > + orientation-switch: > > > > + type: boolean > > > > + description: Specify that this switch can handle orientation switching. > > > > + > > > > + ports: > > > > + $ref: /schemas/graph.yaml#/properties/ports > > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > > + > > > > + properties: > > > > + port@0: > > > > + $ref: /schemas/graph.yaml#/properties/port > > > > + description: Link between the switch and a Type-C connector. > > > > + > > > > + required: > > > > + - port@0 > > > > + > > > > +required: > > > > + - compatible > > > > + - ports > > > > + > > > > +anyOf: > > > > + - required: > > > > + - mode-switch > > > > + - required: > > > > + - orientation-switch > > > > + > > > > +additionalProperties: true > > > > + > > > > +examples: > > > > + - | > > > > + drm-bridge { > > > > + usb-switch { > > > > + compatible = "typec-switch"; > > > > > > Unless this child is supposed to represent what the parent output is > > > connected to, this is just wrong as, at least for the it6505 chip, it > > > doesn't know anything about Type-C functionality. The bridge is > > > just a protocol converter AFAICT. > > > > I'll let Pin-Yen comment on the specifics of the it6505 chip. > > We're all waiting... Yes it6505 is just a protocol converter. But in our use case, the output DP lines are connected to the Type-C ports and the chip has to know which port has DP Alt mode enabled. Does this justify a child node here? Does it make more sense if we we eliminate the usb-switch node here and list the ports in the top level? > > > > If the child node represents what the output is connected to (like a > > > bus), then yes that is a pattern we have used. > > > > For the anx7625 case, the child node does represent what the output is connected > > to (the usb-c-connector via the switch). Does that not qualify? Or do you mean > > the child node should be a usb-c-connector itself? > > > > > For example, a panel > > > represented as child node of a display controller. However, that only > > > works for simple cases, and is a pattern we have gotten away from in > > > favor of using the graph binding. > > > > The child node will still use a OF graph binding to connect to the > > usb-c-connector. > > Is that insufficient to consider a child node usage here? > > By "using the graph binding", do you mean "only use the top-level ports" ? > > I'm trying to clarify this, so that it will inform future versions and patches. > > What I want to see is block diagrams of possible h/w with different > scenarios and then what the binding looks like in those cases. The > switching/muxing could be in the SoC, a bridge chip, a Type C > controller, a standalone mux chip, or ????. If you want a somewhat > genericish binding, then you need to consider all of these. > > I don't really have the b/w to work thru all this (and switch/mux is > just one part of dealing with Type-C). This is just one of about a > hundred patches I get to review a week. > > Rob
On Wed, Jun 29, 2022 at 10:33 PM Pin-yen Lin <treapking@chromium.org> wrote: > > On Wed, Jun 29, 2022 at 2:23 AM Rob Herring <robh@kernel.org> wrote: > > > > On Mon, Jun 27, 2022 at 02:43:39PM -0700, Prashant Malani wrote: > > > Hello Rob, > > > > > > On Mon, Jun 27, 2022 at 2:04 PM Rob Herring <robh@kernel.org> wrote: > > > > > > > > On Wed, Jun 22, 2022 at 05:34:30PM +0000, Prashant Malani wrote: > > > > > Introduce a binding which represents a component that can control the > > > > > routing of USB Type-C data lines as well as address data line > > > > > orientation (based on CC lines' orientation). > > > > > > > > > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > > > > > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > > > > > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > > > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > > > Signed-off-by: Prashant Malani <pmalani@chromium.org> > > > > > --- > > > > > > > > > > Changes since v4: > > > > > - Added Reviewed-by tags. > > > > > - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were > > > > > applied to usb-next) > > > > > > > > > > Changes since v3: > > > > > - No changes. > > > > > > > > > > Changes since v2: > > > > > - Added Reviewed-by and Tested-by tags. > > > > > > > > > > Changes since v1: > > > > > - Removed "items" from compatible. > > > > > - Fixed indentation in example. > > > > > > > > > > .../devicetree/bindings/usb/typec-switch.yaml | 74 +++++++++++++++++++ > > > > > 1 file changed, 74 insertions(+) > > > > > create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > new file mode 100644 > > > > > index 000000000000..78b0190c8543 > > > > > --- /dev/null > > > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > @@ -0,0 +1,74 @@ > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > > > +%YAML 1.2 > > > > > +--- > > > > > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > > + > > > > > +title: USB Type-C Switch > > > > > + > > > > > +maintainers: > > > > > + - Prashant Malani <pmalani@chromium.org> > > > > > + > > > > > +description: > > > > > + A USB Type-C switch represents a component which routes USB Type-C data > > > > > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > > > > > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > > > > > + and cable are operating in. It can also modify lane routing based on > > > > > + the orientation of a connected Type-C peripheral. > > > > > + > > > > > +properties: > > > > > + compatible: > > > > > + const: typec-switch > > > > > + > > > > > + mode-switch: > > > > > + type: boolean > > > > > + description: Specify that this switch can handle alternate mode switching. > > > > > + > > > > > + orientation-switch: > > > > > + type: boolean > > > > > + description: Specify that this switch can handle orientation switching. > > > > > + > > > > > + ports: > > > > > + $ref: /schemas/graph.yaml#/properties/ports > > > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > > > + > > > > > + properties: > > > > > + port@0: > > > > > + $ref: /schemas/graph.yaml#/properties/port > > > > > + description: Link between the switch and a Type-C connector. > > > > > + > > > > > + required: > > > > > + - port@0 > > > > > + > > > > > +required: > > > > > + - compatible > > > > > + - ports > > > > > + > > > > > +anyOf: > > > > > + - required: > > > > > + - mode-switch > > > > > + - required: > > > > > + - orientation-switch > > > > > + > > > > > +additionalProperties: true > > > > > + > > > > > +examples: > > > > > + - | > > > > > + drm-bridge { > > > > > + usb-switch { > > > > > + compatible = "typec-switch"; > > > > > > > > Unless this child is supposed to represent what the parent output is > > > > connected to, this is just wrong as, at least for the it6505 chip, it > > > > doesn't know anything about Type-C functionality. The bridge is > > > > just a protocol converter AFAICT. > > > > > > I'll let Pin-Yen comment on the specifics of the it6505 chip. > > > > We're all waiting... > > Yes it6505 is just a protocol converter. But in our use case, the output DP > lines are connected to the Type-C ports and the chip has to know which > port has DP Alt mode enabled. Does this justify a child node here? > > Does it make more sense if we we eliminate the usb-switch node here > and list the ports in the top level? > > > > > > If the child node represents what the output is connected to (like a > > > > bus), then yes that is a pattern we have used. > > > > > > For the anx7625 case, the child node does represent what the output is connected > > > to (the usb-c-connector via the switch). Does that not qualify? Or do you mean > > > the child node should be a usb-c-connector itself? > > > > > > > For example, a panel > > > > represented as child node of a display controller. However, that only > > > > works for simple cases, and is a pattern we have gotten away from in > > > > favor of using the graph binding. > > > > > > The child node will still use a OF graph binding to connect to the > > > usb-c-connector. > > > Is that insufficient to consider a child node usage here? > > > By "using the graph binding", do you mean "only use the top-level ports" ? > > > I'm trying to clarify this, so that it will inform future versions and patches. > > > > What I want to see is block diagrams of possible h/w with different > > scenarios and then what the binding looks like in those cases. The > > switching/muxing could be in the SoC, a bridge chip, a Type C > > controller, a standalone mux chip, or ????. If you want a somewhat > > genericish binding, then you need to consider all of these. Then, is it suitable to put the switch binding into the drivers own bindings (i.e., the bindings for it6505 and anx7625), and introduce some helper functions to eliminate the duplication in the code? Though we will have two similar bindings in two drivers with this approach. > > > > I don't really have the b/w to work thru all this (and switch/mux is > > just one part of dealing with Type-C). This is just one of about a > > hundred patches I get to review a week. > > > > Rob
On Wed, Jun 29, 2022 at 9:01 AM Pin-yen Lin <treapking@chromium.org> wrote: > > On Wed, Jun 29, 2022 at 10:33 PM Pin-yen Lin <treapking@chromium.org> wrote: > > > > On Wed, Jun 29, 2022 at 2:23 AM Rob Herring <robh@kernel.org> wrote: > > > > > > On Mon, Jun 27, 2022 at 02:43:39PM -0700, Prashant Malani wrote: > > > > Hello Rob, > > > > > > > > On Mon, Jun 27, 2022 at 2:04 PM Rob Herring <robh@kernel.org> wrote: > > > > > > > > > > On Wed, Jun 22, 2022 at 05:34:30PM +0000, Prashant Malani wrote: > > > > > > Introduce a binding which represents a component that can control the > > > > > > routing of USB Type-C data lines as well as address data line > > > > > > orientation (based on CC lines' orientation). > > > > > > > > > > > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > > > > > > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > > > > > > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > > > > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > > > > > > Signed-off-by: Prashant Malani <pmalani@chromium.org> > > > > > > --- > > > > > > > > > > > > Changes since v4: > > > > > > - Added Reviewed-by tags. > > > > > > - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were > > > > > > applied to usb-next) > > > > > > > > > > > > Changes since v3: > > > > > > - No changes. > > > > > > > > > > > > Changes since v2: > > > > > > - Added Reviewed-by and Tested-by tags. > > > > > > > > > > > > Changes since v1: > > > > > > - Removed "items" from compatible. > > > > > > - Fixed indentation in example. > > > > > > > > > > > > .../devicetree/bindings/usb/typec-switch.yaml | 74 +++++++++++++++++++ > > > > > > 1 file changed, 74 insertions(+) > > > > > > create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > > new file mode 100644 > > > > > > index 000000000000..78b0190c8543 > > > > > > --- /dev/null > > > > > > +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml > > > > > > @@ -0,0 +1,74 @@ > > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > > > > +%YAML 1.2 > > > > > > +--- > > > > > > +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > > > + > > > > > > +title: USB Type-C Switch > > > > > > + > > > > > > +maintainers: > > > > > > + - Prashant Malani <pmalani@chromium.org> > > > > > > + > > > > > > +description: > > > > > > + A USB Type-C switch represents a component which routes USB Type-C data > > > > > > + lines to various protocol host controllers (e.g USB, VESA DisplayPort, > > > > > > + Thunderbolt etc.) depending on which mode the Type-C port, port partner > > > > > > + and cable are operating in. It can also modify lane routing based on > > > > > > + the orientation of a connected Type-C peripheral. > > > > > > + > > > > > > +properties: > > > > > > + compatible: > > > > > > + const: typec-switch > > > > > > + > > > > > > + mode-switch: > > > > > > + type: boolean > > > > > > + description: Specify that this switch can handle alternate mode switching. > > > > > > + > > > > > > + orientation-switch: > > > > > > + type: boolean > > > > > > + description: Specify that this switch can handle orientation switching. > > > > > > + > > > > > > + ports: > > > > > > + $ref: /schemas/graph.yaml#/properties/ports > > > > > > + description: OF graph binding modelling data lines to the Type-C switch. > > > > > > + > > > > > > + properties: > > > > > > + port@0: > > > > > > + $ref: /schemas/graph.yaml#/properties/port > > > > > > + description: Link between the switch and a Type-C connector. > > > > > > + > > > > > > + required: > > > > > > + - port@0 > > > > > > + > > > > > > +required: > > > > > > + - compatible > > > > > > + - ports > > > > > > + > > > > > > +anyOf: > > > > > > + - required: > > > > > > + - mode-switch > > > > > > + - required: > > > > > > + - orientation-switch > > > > > > + > > > > > > +additionalProperties: true > > > > > > + > > > > > > +examples: > > > > > > + - | > > > > > > + drm-bridge { > > > > > > + usb-switch { > > > > > > + compatible = "typec-switch"; > > > > > > > > > > Unless this child is supposed to represent what the parent output is > > > > > connected to, this is just wrong as, at least for the it6505 chip, it > > > > > doesn't know anything about Type-C functionality. The bridge is > > > > > just a protocol converter AFAICT. > > > > > > > > I'll let Pin-Yen comment on the specifics of the it6505 chip. > > > > > > We're all waiting... > > > > Yes it6505 is just a protocol converter. But in our use case, the output DP > > lines are connected to the Type-C ports and the chip has to know which > > port has DP Alt mode enabled. Does this justify a child node here? > > > > Does it make more sense if we we eliminate the usb-switch node here > > and list the ports in the top level? In the it6505 node? No, the it6505 h/w knows nothing about Type-C switching so neither should its binding. What device controls the switching in this case? Again, block diagrams please if you want advice on what the binding should look like. > > > > > If the child node represents what the output is connected to (like a > > > > > bus), then yes that is a pattern we have used. > > > > > > > > For the anx7625 case, the child node does represent what the output is connected > > > > to (the usb-c-connector via the switch). Does that not qualify? Or do you mean > > > > the child node should be a usb-c-connector itself? > > > > > > > > > For example, a panel > > > > > represented as child node of a display controller. However, that only > > > > > works for simple cases, and is a pattern we have gotten away from in > > > > > favor of using the graph binding. > > > > > > > > The child node will still use a OF graph binding to connect to the > > > > usb-c-connector. > > > > Is that insufficient to consider a child node usage here? > > > > By "using the graph binding", do you mean "only use the top-level ports" ? > > > > I'm trying to clarify this, so that it will inform future versions and patches. > > > > > > What I want to see is block diagrams of possible h/w with different > > > scenarios and then what the binding looks like in those cases. The > > > switching/muxing could be in the SoC, a bridge chip, a Type C > > > controller, a standalone mux chip, or ????. If you want a somewhat > > > genericish binding, then you need to consider all of these. > > Then, is it suitable to put the switch binding into the drivers own bindings > (i.e., the bindings for it6505 and anx7625), and introduce some helper > functions to eliminate the duplication in the code? Only for h/w devices that have switch h/w. > Though we will have two similar bindings in two drivers with this approach. While the anx7625 driver having Type-C awareness makes sense given it has a switch and a type-C controller, that doesn't make sense for it6505 (and every other bridge driver that's just providing DP output). Rob
Quoting Rob Herring (2022-06-29 10:58:52) > On Wed, Jun 29, 2022 at 9:01 AM Pin-yen Lin <treapking@chromium.org> wrote: > > > > > > Yes it6505 is just a protocol converter. But in our use case, the output DP > > > lines are connected to the Type-C ports and the chip has to know which > > > port has DP Alt mode enabled. Does this justify a child node here? > > > > > > Does it make more sense if we we eliminate the usb-switch node here > > > and list the ports in the top level? > > In the it6505 node? No, the it6505 h/w knows nothing about Type-C > switching so neither should its binding. > > What device controls the switching in this case? Again, block diagrams > please if you want advice on what the binding should look like. My understanding is there are 4 DP lanes on it6505 and two lanes are connected to one usb-c-connector and the other two lanes are connected to a different usb-c-connector. The IT6505 driver will send DP out on the associated two DP lanes depending on which usb-c-connector has DP pins assigned by the typec manager. +-------+ | | +--------+ /----+ usb-c | | IT6505 | / /---+ | | +------------ lane 0 ------/ / | | | +------------ lane 1 -------/ +-------+ DPI -----+ | | | +-------+ | | | | | +------------ lane 2 -------------+ usb-c | | +------------ lane 3 -------------+ | | | | | +--------+ +-------+ The bridge is a mux that steers DP to one or the other usb-c-connector based on what the typec manager decides. I would expect this to be described with the existing port binding in the it6505 node. The binding would need to be extended to describe the output side. bridge@5c { compatible = "ite,it6505"; ... ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; it6505_in: endpoint { remote-endpoint = <&dpi_out>; }; }; port@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; it6505_out_lanes_01: endpoint@0 { reg = <0> data-lanes = <0 1>; remote-endpoint = <&typec0>; }; it6505_out_lanes_23: endpoint@1 { reg = <1> data-lanes = <2 3>; remote-endpoint = <&typec1>; }; }; }; }; usb-c-connector { compatible = "usb-c-connector"; .... ports { #address-cells = <1>; #size-cells = <0>; port@1 { reg = <1>; typec0: endpoint { remote-endpoint = <&it6505_out_lanes_01>; }; }; }; }; Note: port@1 in usb-c-connector above is for superspeed lines, which technically DP reuses. But we can also shove USB3 superspeed lines over the other two superspeed pins in the usb-c-connector pinout. Probably port@1 should have two endpoints so we can connect usb superspeed lines there in addition to DP lines. Another use case would be to have the IT6505 send 4 lanes of DP to a dp-connector. Or send one lane of DP to 4 dp-connectors? Sounds awful but possible if this bridge can drive one lane DP out on any DP output lane. bridge@5c { compatible = "ite,it6505"; ... ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; it6505_in: endpoint { remote-endpoint = <&dpi_out>; }; }; port@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; it6505_out_lane_0: endpoint@0 { reg = <0> data-lanes = <0>; remote-endpoint = <&dp0>; }; it6505_out_lane_1: endpoint@1 { reg = <1> data-lanes = <1>; remote-endpoint = <&dp1>; }; it6505_out_lane_2: endpoint@2 { reg = <2> data-lanes = <2>; remote-endpoint = <&dp1>; }; it6505_out_lane_3: endpoint@3 { reg = <3> data-lanes = <3>; remote-endpoint = <&dp1>; }; }; }; }; Or we could send 4 lanes of DP to a typec redriver that's controlled by firmware outside of the kernel where the redriver takes in 4 lanes DP and USB3 and muxes USB or USB+DP or just DP. bridge@5c { compatible = "ite,it6505"; ... ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; it6505_in: endpoint { remote-endpoint = <&dpi_out>; }; }; port@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; it6505_out: endpoint@0 { reg = <0> data-lanes = <0 1 2 3>; remote-endpoint = <&cros_ec_typec_dp_in>; }; }; }; }; cros_ec@0 { compatible = "google,cros-ec-spi"; ... cros_ec_typec: typec { compatible = "google,cros-ec-typec"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { cros_ec_typec_dp_in: endpoint { remote-endpoint = <&it6505_out>; }; }; }; }; }; In this case we would want to have cros_ec_typec describe some sort of input graph binding to accept DP. I imagine the EC as a dp-bridge in this scenario, where it takes in DP and muxes it along with USB onto a usb-c-connector. If the EC is managing multiple usb-c-connectors then the typec framework may need help determining which port DP is going to, especially in the case that two DP bridges are used and they're both sent to the EC so that the EC can mux them onto a usb-c-connector along with USB. (I can draw more block diagrams if you prefer) > > > > > > > If the child node represents what the output is connected to (like a > > > > > > bus), then yes that is a pattern we have used. > > > > > > > > > > For the anx7625 case, the child node does represent what the output is connected > > > > > to (the usb-c-connector via the switch). Does that not qualify? Or do you mean > > > > > the child node should be a usb-c-connector itself? > > > > > > > > > > > For example, a panel > > > > > > represented as child node of a display controller. However, that only > > > > > > works for simple cases, and is a pattern we have gotten away from in > > > > > > favor of using the graph binding. > > > > > > > > > > The child node will still use a OF graph binding to connect to the > > > > > usb-c-connector. > > > > > Is that insufficient to consider a child node usage here? > > > > > By "using the graph binding", do you mean "only use the top-level ports" ? > > > > > I'm trying to clarify this, so that it will inform future versions and patches. > > > > > > > > What I want to see is block diagrams of possible h/w with different > > > > scenarios and then what the binding looks like in those cases. The > > > > switching/muxing could be in the SoC, a bridge chip, a Type C > > > > controller, a standalone mux chip, or ????. If you want a somewhat > > > > genericish binding, then you need to consider all of these. > > > > Then, is it suitable to put the switch binding into the drivers own bindings > > (i.e., the bindings for it6505 and anx7625), and introduce some helper > > functions to eliminate the duplication in the code? > > Only for h/w devices that have switch h/w. > > > Though we will have two similar bindings in two drivers with this approach. > > While the anx7625 driver having Type-C awareness makes sense given it > has a switch and a type-C controller, that doesn't make sense for > it6505 (and every other bridge driver that's just providing DP > output). > I don't see the benefit to making a genericish binding for typec switches, even if the hardware has typec awareness like anx7625. It looks like the graph binding can already handle what we need. By putting it in the top-level ports node we have one way to describe the input/output of the device instead of describing it in the top-level in the display connector case and the child typec switch node in the usb c connector case. I think the difficulty comes from the combinatorial explosion of possible configurations. As evidenced here, hardware engineers can take a DP bridge and use it as a DP mux as long as the bridge has lane control. Or they can take a device like anx7625 and ignore the USB aspect and use the internal crosspoint switch as a DP mux. The anx7625 part could be a MIPI-to-DP display bridge plus mux that is connected to two dp-connectors, in which case typec isn't even involved, but we could mux between two dp connectors. Also, the typec framework would like to simply walk the graph from the usb-c-connector looking for nodes that have 'mode-switch' or 'orientation-switch' properties and treat those devices as the typec switches for the connector. This means that we have to add these typec properties like 'mode-switch' to something like the IT6505 bridge binding, which is a little awkward. I wonder if those properties aren't really required. Would it be sufficient if the framework could walk the graph and look for registered typec switches in the kernel that have a matching of_node?
On Wed, Jun 29, 2022 at 2:58 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > What device controls the switching in this case? Again, block diagrams > > please if you want advice on what the binding should look like. > > My understanding is there are 4 DP lanes on it6505 and two lanes are > connected to one usb-c-connector and the other two lanes are connected > to a different usb-c-connector. The IT6505 driver will send DP out on > the associated two DP lanes depending on which usb-c-connector has DP > pins assigned by the typec manager. > > +-------+ > | | > +--------+ /----+ usb-c | > | IT6505 | / /---+ | > | +------------ lane 0 ------/ / | | > | +------------ lane 1 -------/ +-------+ > DPI -----+ | > | | +-------+ > | | | | > | +------------ lane 2 -------------+ usb-c | > | +------------ lane 3 -------------+ | > | | | | > +--------+ +-------+ > > The bridge is a mux that steers DP to one or the other usb-c-connector > based on what the typec manager decides. > > I would expect this to be described with the existing port binding in > the it6505 node. The binding would need to be extended to describe the > output side. > > bridge@5c { > compatible = "ite,it6505"; We'll need a top level "mode-switch" property here. > ... > > ports { > #address-cells = <1>; > #size-cells = <0>; > > port@0 { > reg = <0>; > it6505_in: endpoint { > remote-endpoint = <&dpi_out>; > }; > }; > > port@1 { > #address-cells = <1>; > #size-cells = <0>; > reg = <1>; > > it6505_out_lanes_01: endpoint@0 { > reg = <0> > data-lanes = <0 1>; > remote-endpoint = <&typec0>; > }; > > it6505_out_lanes_23: endpoint@1 { > reg = <1> > data-lanes = <2 3>; > remote-endpoint = <&typec1>; > }; > }; > }; > }; > > usb-c-connector { > compatible = "usb-c-connector"; > .... > ports { > #address-cells = <1>; > #size-cells = <0>; > > port@1 { > reg = <1>; > typec0: endpoint { > remote-endpoint = <&it6505_out_lanes_01>; > }; > }; > }; > }; We can adopt this binding, but from what I gathered in this thread, that shouldn't be done, because IT6505 isn't meant to be aware of Type-C connections at all. > > I don't see the benefit to making a genericish binding for typec > switches, even if the hardware has typec awareness like anx7625. It > looks like the graph binding can already handle what we need. By putting > it in the top-level ports node we have one way to describe the > input/output of the device instead of describing it in the top-level in > the display connector case and the child typec switch node in the usb c > connector case. Ack, I'll drop the generic binding for future revisions. > > I think the difficulty comes from the combinatorial explosion of > possible configurations. As evidenced here, hardware engineers can take > a DP bridge and use it as a DP mux as long as the bridge has lane > control. Or they can take a device like anx7625 and ignore the USB > aspect and use the internal crosspoint switch as a DP mux. The anx7625 > part could be a MIPI-to-DP display bridge plus mux that is connected to > two dp-connectors, in which case typec isn't even involved, but we could > mux between two dp connectors. Each containing a single DP lane, right? I think that will not be a valid configuration, since there is only 1 HPD pin (so it's assuming both DP lanes go to the same DP sink). But yes, your larger point is valid: h/w engineers can repurpose these bridges in ways the datasheet doesn't originally anticipate. > > Also, the typec framework would like to simply walk the graph from the > usb-c-connector looking for nodes that have 'mode-switch' or > 'orientation-switch' properties and treat those devices as the typec > switches for the connector. This means that we have to add these typec > properties like 'mode-switch' to something like the IT6505 bridge > binding, which is a little awkward. I wonder if those properties aren't > really required. Would it be sufficient if the framework could walk the > graph and look for registered typec switches in the kernel that have a > matching of_node? My interpretation of the current mode-switch search code [1] is that a top level property of "mode-switch" is required. [1] https://elixir.bootlin.com/linux/v5.19-rc4/source/drivers/usb/typec/mux.c#L347
Quoting Prashant Malani (2022-06-29 15:55:10) > On Wed, Jun 29, 2022 at 2:58 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > My understanding is there are 4 DP lanes on it6505 and two lanes are > > connected to one usb-c-connector and the other two lanes are connected > > to a different usb-c-connector. The IT6505 driver will send DP out on > > the associated two DP lanes depending on which usb-c-connector has DP > > pins assigned by the typec manager. [...] > > We can adopt this binding, but from what I gathered in this thread, that > shouldn't be done, because IT6505 isn't meant to be aware of Type-C > connections at all. How will the driver know which usb-c-connector to route DP to without making the binding aware of typec connections? > > > > I think the difficulty comes from the combinatorial explosion of > > possible configurations. As evidenced here, hardware engineers can take > > a DP bridge and use it as a DP mux as long as the bridge has lane > > control. Or they can take a device like anx7625 and ignore the USB > > aspect and use the internal crosspoint switch as a DP mux. The anx7625 > > part could be a MIPI-to-DP display bridge plus mux that is connected to > > two dp-connectors, in which case typec isn't even involved, but we could > > mux between two dp connectors. > > Each containing a single DP lane, right? Yes. > I think that will not be a valid configuration, since there is only 1 HPD > pin (so it's assuming both DP lanes go to the same DP sink). HPD can be signalled out of band, or not at all (no-hpd). I suspect it's valid to ignore/disconnect the HPD pin here and start/stop DP when, for example, the HPD pin toggles within a dp-connector. HPD could be signaled directly to the kernel via an out of band gpio going from the dp-connector to the SoC. In this case HPD for each dp-connector could be a different gpio and the driver may be required to arbitrate between the two dp-connectors with some 'first to signal wins' logic or something. > > But yes, your larger point is valid: h/w engineers can repurpose these > bridges in ways the datasheet doesn't originally anticipate. Yeah, I'm also trying to say that devices with typec logic may not be used for typec purposes. > > > > > Also, the typec framework would like to simply walk the graph from the > > usb-c-connector looking for nodes that have 'mode-switch' or > > 'orientation-switch' properties and treat those devices as the typec > > switches for the connector. This means that we have to add these typec > > properties like 'mode-switch' to something like the IT6505 bridge > > binding, which is a little awkward. I wonder if those properties aren't > > really required. Would it be sufficient if the framework could walk the > > graph and look for registered typec switches in the kernel that have a > > matching of_node? > > My interpretation of the current mode-switch search code [1] is that > a top level property of "mode-switch" is required. Yeah that's how it is right now, but does it have to stay that way? Could the code search the graph and look for a matching node that's registered with the typec framework? The goal is to avoid adding typec properties like 'mode-switch' to bindings like bridge converters that aren't expected to work with typec. Hopefully the binding can be written with the output pins in mind and what modes on those pins the hardware supports (e.g. two lanes on anx7625 can't be split apart whereas on it6505 each pair can be used directly).
(CC+ Bjorn) On Wed, Jun 29, 2022 at 4:55 PM Stephen Boyd <swboyd@chromium.org> wrote: > > Quoting Prashant Malani (2022-06-29 15:55:10) > > On Wed, Jun 29, 2022 at 2:58 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > My understanding is there are 4 DP lanes on it6505 and two lanes are > > > connected to one usb-c-connector and the other two lanes are connected > > > to a different usb-c-connector. The IT6505 driver will send DP out on > > > the associated two DP lanes depending on which usb-c-connector has DP > > > pins assigned by the typec manager. > [...] > > > > We can adopt this binding, but from what I gathered in this thread, that > > shouldn't be done, because IT6505 isn't meant to be aware of Type-C > > connections at all. > > How will the driver know which usb-c-connector to route DP to without > making the binding aware of typec connections? I agree with you; I'm saying my interpretation of the comments of this thread are that it's not the intended usage of the it6505 part, so the driver shouldn't be updated to support that. > > HPD can be signalled out of band, or not at all (no-hpd). I suspect it's > valid to ignore/disconnect the HPD pin here and start/stop DP when, for > example, the HPD pin toggles within a dp-connector. HPD could be > signaled directly to the kernel via an out of band gpio going from the > dp-connector to the SoC. In this case HPD for each dp-connector could be > a different gpio and the driver may be required to arbitrate between the > two dp-connectors with some 'first to signal wins' logic or something. Sure, it's possible. I just didn't see anything in the anx7625 datasheet to suggest it supported 2x1-lane DP outputs. For that matter I don't think even it6505 supports > 1 DP sink (based on my reading of the datasheet), but I don't have too much experience with these parts. > > My interpretation of the current mode-switch search code [1] is that > > a top level property of "mode-switch" is required. > > Yeah that's how it is right now, but does it have to stay that way? > Could the code search the graph and look for a matching node that's > registered with the typec framework? I'll have to get back to you on that after reading the code a bit more. Maybe Heikki or Bjorn have some comments about it. The ACPI Type-C ports do require a device handle labelled "mode-switch" which points to the switch device.
On Thu, Jun 30, 2022 at 10:10:32AM -0700, Prashant Malani wrote: > (CC+ Bjorn) > > On Wed, Jun 29, 2022 at 4:55 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > Quoting Prashant Malani (2022-06-29 15:55:10) > > > On Wed, Jun 29, 2022 at 2:58 PM Stephen Boyd <swboyd@chromium.org> wrote: > > > > > > > > My understanding is there are 4 DP lanes on it6505 and two lanes are > > > > connected to one usb-c-connector and the other two lanes are connected > > > > to a different usb-c-connector. The IT6505 driver will send DP out on > > > > the associated two DP lanes depending on which usb-c-connector has DP > > > > pins assigned by the typec manager. > > [...] > > > > > > We can adopt this binding, but from what I gathered in this thread, that > > > shouldn't be done, because IT6505 isn't meant to be aware of Type-C > > > connections at all. > > > > How will the driver know which usb-c-connector to route DP to without > > making the binding aware of typec connections? > > I agree with you; I'm saying my interpretation of the comments of this > thread are that it's not the intended usage of the it6505 part, so the driver > shouldn't be updated to support that. That's not the right interpretation. There should not be some Type-C specific child mux/switch node because the device has no such h/w within it. Assuming all the possibilities Stephen outlined are valid, it's clear this lane selection has nothing to do with Type-C. It does have an output port for its DP output already and using that to describe the connection to DP connector(s) and/or Type-C connector(s) should be handled. Whether the driver is type-C aware is a separate question from the binding. I would think the driver just needs to be told (or it can ask) which endpoint should be active and it just enables output on the corresponding lanes for that endpoint. I'm not sure if all DP bridge chips have the same flexibility on their output lanes, but I would assume many do and we don't want to be duplicating the same code to handle that in every bridge driver. Rob
On Tue, Jul 12, 2022 at 10:45 AM Rob Herring <robh@kernel.org> wrote: > > > I agree with you; I'm saying my interpretation of the comments of this > > thread are that it's not the intended usage of the it6505 part, so the driver > > shouldn't be updated to support that. > > That's not the right interpretation. There should not be some Type-C > specific child mux/switch node because the device has no such h/w within > it. Assuming all the possibilities Stephen outlined are valid, it's > clear this lane selection has nothing to do with Type-C. It does have an > output port for its DP output already and using that to describe the > connection to DP connector(s) and/or Type-C connector(s) should be > handled. Got it. Thanks for the clarification. > > Whether the driver is type-C aware is a separate question from the > binding. I would think the driver just needs to be told (or it can ask) > which endpoint should be active and it just enables output on the > corresponding lanes for that endpoint. Is it acceptable to tag the end-points with a "mode-switch" / "orientation-switch" property? Something like the following: ``` dp-bridge@5c { compatible = "ite,it6505"; ... port { #adderss-cells = <1>; #size-cells = <0>; ite_typec0: endpoint@0 { reg = <0>; mode-switch; remote-endpoint = <&typec_connector0>; }; ite_typec1: endpoint@1 { reg = <1>; mode-switch; remote-endpoint = <&typec_connector1>; }; }; }; ``` Or should the DRM bridge device binding not have those properties in the end-points either? The reasons those are required are: - The Type-C matching code looks for the "mode-switch" identifier in the fwnode while performing the switch matching [1] - While we can look up whether the remote-endpoint is a "usb-c-connector" in the bridge driver the "mode-switch"/"orientation-switch" property tells the bridge driver whether to register just a mode-switch, an orientation switch or both. Best regards, - Prashant [1] https://elixir.bootlin.com/linux/v5.19-rc6/source/drivers/usb/typec/mux.c#L347
Hi Rob, On Jul 12 11:45, Rob Herring wrote: > > That's not the right interpretation. There should not be some Type-C > specific child mux/switch node because the device has no such h/w within > it. Assuming all the possibilities Stephen outlined are valid, it's > clear this lane selection has nothing to do with Type-C. It does have an > output port for its DP output already and using that to describe the > connection to DP connector(s) and/or Type-C connector(s) should be > handled. > Rob Below I've listed the proposal binding (for the Type-C connector) along with 2 sample hardware diagrams and corresponding DT. The updated binding in usb-c-connector would be as follows: diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index ae515651fc6b..a043b09cb8ec 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -183,6 +183,30 @@ properties: port@1: $ref: /schemas/graph.yaml#/properties/port description: Super Speed (SS), present in SS capable connectors. + properties: + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + patternProperties: + "^endpoint@[0-1]$": + $ref: /schemas/graph.yaml#/$defs/endpoint-base + description: + Endpoints for the two SS lanes. endpoint@0 refers to SSTRX1 (A2,A3,B10,B11) + and endpoint@1 refers to SSTRX2 (B2,B3,A10,A11). + additionalProperties: false + + properties: + reg: + maxItems: 1 + + remote-endpoint: true + + required: + - reg + - remote-endpoint port@2: $ref: /schemas/graph.yaml#/properties/port Here are 2 examples of how that would look on some existing hardware: Example 1. 2 usb-c-connectors connecting to 1 drm bridge / DP switch: Here is the diagram we are using on the MTK platform: SOC +---------------------+ C0 | | +----------+ 2 lane +--------+ | | | +---------/---------+ SSTRX1 | | | | | | | | MIPI DPI | | | 2 lane | | | +------------+ ANX 7625 +---/-----+ +----+ SSTRX2 | | | | | | | +--------+ | | +----------+ | | +---------------------+ | | | | +----------+ 2 lane | | C1 | | | +----/----C----+ +--------+ | USB3 HC | 2 lane | | | | SSTRX1 | | +-----/------+ USB3 HUB | +---------+ | | (host controller) | | | 2 lane | | | | | +---------/---------+ SSTRX2 | +---------------------+ | | | | +----------+ +--------+ Some platforms use it6505, so that can be swapped in for anx7625 without any change to the rest of the hardware diagram. From the above, we can see that it is helpful to describe the Type-C SS lines as 2 endpoints: - 1 for SSTX1+SSRX1 (A2,A3 + B10,B11) - 1 for SSTX2+SSRX2 (B2,B3 + A10, A11) A device tree for this would look as follows: // Type-C port driver ec { ... cros_ec_typec { ... usb-c0 { compatible = "usb-c-connector"; ports { hs : port@0 { ... }; ss: port@1 { reg = <1>; c0_sstrx1: endpoint@0 { reg = <0>; remote-endpoint = <&anx7625_out0>; }; c0_sstrx2: endpoint@0 { reg = <0>; remote-endpoint = <&usb3hub_out0>; }; }; sbu : port@2 { ... }; }; }; usb-c1 { compatible = "usb-c-connector"; ports { hs : port@0 { ... }; ss: port@1 { reg = <1>; c1_sstrx1: endpoint@0 { reg = <0>; remote-endpoint = <&anx7625_out1>; }; c1_sstrx2: endpoint@0 { reg = <0>; remote-endpoint = <&usb3hub_out1>; }; }; sbu : port@2 { ... }; }; }; }; }; // DRM bridge / Type-C mode switch anx_bridge: anx7625@58 { compatible = "analogix,anx7625"; reg = <0x58>; ... // Input from DP controller port@0 { reg = <0>; ... }; // Output to Type-C connector / DP panel port@1 { reg = <1>; anx7625_out0: endpoint@0 { reg = <0>; mode-switch; remote-endpoint = <&c0_sstrx1>; }; anx7625_out1: endpoint@1 { reg = <1>; mode-switch; remote-endpoint = <&c1_sstrx1>; }; }; }; // USB3 hub usb3hub: foo_hub { ... ports@0 { // End point connected to USB3 host controller on SOC. }; port@1 { reg = <1>; foo_hub_out0: endpoint@0 { reg = <0>; mode-switch; ---> See c.) later remote-endpoint = <&c0_sstrx2>; }; foo_hub_out1: endpoint@1 { reg = <1>; mode-switch; remote-endpoint = <&c1_sstrx2>; }; }; }; Notes: - On the Chrome OS platform, the USB3 Hub is controlled by the EC, so we don't really need to describe that connection, but I've added a minimal one here just to show how the graph connection would work if the HUB was controlled by the SoC. - The above assumes that other hardware is controlling orientation. We can add "orientation-switch" drivers along the graph path if there is other hardware which controls orientation. Example 2: 1 USB-C connector connected to 1 drm-bridge/ mode-switch I've tried to use Bjorn's example [1], but I might have made some mistakes since I don't have access to the schematic. SoC +------------------------------------------+ | | | +---------------+ | | | | | | | DP ctrllr | +---------+ | C0 | | +-------+ | | 2 lane +----------+ | +---------------+ | QMP +-----+-----/--------+ SSTRX1 | | | PHY | | | | | +-------------+ 2 lane | | | 2 lane | | | | +----/----+ +-----+-----/--------+ SSTRX2 | | | dwc3 | +---------+ | | | | | | | | | | | | +---------+ | | | | | +---------+ HS PHY | | HS lanes | | | +-------------+ | +-----+----/---------+ D +/- | | | | | +----------+ | +---------+ | | | +------------------------------------------+ The DT would look something like this (borrowing from Stephen's example [2]): qmp { mode-switch; ----> See b.) later. orientation-switch; ports { qmp_usb_in: port@0 { reg = <0>; remote-endpoint = <&usb3_phy_out>; }; qmp_dp_in: port@1 { reg = <1>; remote-endpoint = <&dp_phy_out>; }; port@2 { reg = <2>; qmp_usb_dp_out0: endpoint@0 { reg = <0>; remote-endpoint = <&c0_sstrx1>; }; qmp_usb_dp_out1: endpoint@1 { reg = <1>; remote-endpoint = <&c0_sstrx2>; }; }; }; dp-phy { ports { dp_phy_out: port { remote-endpoint = <&qmp_dp_in>; }; }; }; dwc3: usb-phy { ports { usb3_phy_out: port@0 { reg = <0>; remote-endpoint = <&qmp_usb_in>; }; }; }; glink { c0: usb-c-connector { compatible = "usb-c-connector"; ports { hs: port@0 { reg = <0>; endpoint@0 { reg = <0>; remote-endpoint = <&hs_phy_out>; }; }; ss: port@1 { reg = <1>; c0_sstrx1: endpoint@0 { reg = <0>; remote-endpoint = <&qmp_usb_dp_out0>; }; c0_sstrx2: endpoint@1 { reg = <1>; remote-endpoint = <&qmp_usb_dp_out1>; }; }; }; }; }; Notes: a. This proposal doesn't deal with the DRM bridge HPD forwarding; I believe that is covered by Stephen's example/proposal in [2], and can be addressed separately. That said, this binding is compatible with the proposal in [2], that is, make the "mode-switch" driver a drm-bridge and forward the HPD info to the upstream DRM-bridge (DP controller). The driver implementing "mode-switch" will be able to do that, since it gets DP status/attention VDOS with HPD info from the Type-C port driver. b. If both SSTRX pairs from a connector are routed to the same hardware block (example 2) then the device would keep "mode-switch" as a top level property (and the fwnode associated with "mode-switch" is the drm-bridge device). c. If SSTRX pairs from 2 connectors are routed to the same hardware block (example 1), then each end-point which is connected to the USB-C connector will have a "mode-switch" property in its end-point. There will be 2 mode switches registered here, and the fwnode for each "mode-switch" is the end-point node. b.) and c.) can be handled by Type C mux registration and matching code. We already have 3 mux devs for each mux [3]. For the single mode-switch case, mux_dev[1] will just refer to the top-level mode-switch registered by the DRM bridge / switch driver (example 1). For the 2 mode-switch case, typec_mux_dev[1] will have 2 child typec_mux_dev's, each of which represents the mode-switches registered by the DRM bridge / switch driver. Introducing this indirection means the port driver / alternate mode driver don't need to care about how the connectors are routed; the framework will just call the mux_set() function on the mux_dev() or its children if it has any. The benefit of this approach is existing bindings (which just assume 1 endpoint from usb-c-connector/port@1) should continue to work without any changes. Why don't we use data lanes for the usb-c-connector endpoints? I guess we could, but I am not a fan of adding the extra data-lane parsing logic to the Type-C framework (I don't think drivers need that level of detail from the connector binding). And even then, we will still need an extra end-point if the lanes of the USB-C connector are routed to different hardware blocks. The Type-C connector spec doesn't specify any alternate modes with < 1 SSTRX pair, so the most we can ever have (short of a major change to the spec) is 2 SSTRX end points for a connector each being routed to different hardware blocks. Codifying these as endpoint@0 and endpoint@1 in the usb-c-connector binding seems to line up nicely with this detail of the spec. Thanks, -Prashant [1] https://lore.kernel.org/linux-usb/Yv1y9Wjp16CstJvK@baldur/ [2] https://lore.kernel.org/linux-usb/CAE-0n52-QVeUVCB1qZzPbYyrb1drrbJf6H2DEEW9bOE6mh7egw@mail.gmail.com/ [3] https://elixir.bootlin.com/linux/v6.0-rc3/source/drivers/usb/typec/mux.c#L259
Hi folks, On Fri, Sep 2, 2022 at 12:41 AM Prashant Malani <pmalani@chromium.org> wrote: > > Hi Rob, > > On Jul 12 11:45, Rob Herring wrote: > > > > That's not the right interpretation. There should not be some Type-C > > specific child mux/switch node because the device has no such h/w within > > it. Assuming all the possibilities Stephen outlined are valid, it's > > clear this lane selection has nothing to do with Type-C. It does have an > > output port for its DP output already and using that to describe the > > connection to DP connector(s) and/or Type-C connector(s) should be > > handled. > > Rob > > Below I've listed the proposal binding (for the Type-C connector) along > with 2 sample hardware diagrams and corresponding DT. Any thoughts about this proposal? > > The updated binding in usb-c-connector would be as follows: > > diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml > index ae515651fc6b..a043b09cb8ec 100644 > --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml > +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml > @@ -183,6 +183,30 @@ properties: > port@1: > $ref: /schemas/graph.yaml#/properties/port > description: Super Speed (SS), present in SS capable connectors. > + properties: > + '#address-cells': > + const: 1 > + > + '#size-cells': > + const: 0 > + > + patternProperties: > + "^endpoint@[0-1]$": > + $ref: /schemas/graph.yaml#/$defs/endpoint-base > + description: > + Endpoints for the two SS lanes. endpoint@0 refers to SSTRX1 (A2,A3,B10,B11) > + and endpoint@1 refers to SSTRX2 (B2,B3,A10,A11). > + additionalProperties: false > + > + properties: > + reg: > + maxItems: 1 > + > + remote-endpoint: true > + > + required: > + - reg > + - remote-endpoint > > port@2: > $ref: /schemas/graph.yaml#/properties/port > > Here are 2 examples of how that would look on some existing hardware: > > Example 1. 2 usb-c-connectors connecting to 1 drm bridge / DP switch: > > Here is the diagram we are using on the MTK platform: > > SOC > +---------------------+ C0 > | | +----------+ 2 lane +--------+ > | | | +---------/---------+ SSTRX1 | > | | | | | | > | MIPI DPI | | | 2 lane | | > | +------------+ ANX 7625 +---/-----+ +----+ SSTRX2 | > | | | | | | +--------+ > | | +----------+ | | > +---------------------+ | | > | | +----------+ 2 lane | | C1 > | | | +----/----C----+ +--------+ > | USB3 HC | 2 lane | | | | SSTRX1 | > | +-----/------+ USB3 HUB | +---------+ | > | (host controller) | | | 2 lane | | > | | | +---------/---------+ SSTRX2 | > +---------------------+ | | | | > +----------+ +--------+ > > Some platforms use it6505, so that can be swapped in for anx7625 > without any change to the rest of the hardware diagram. > > From the above, we can see that it is helpful to describe the > Type-C SS lines as 2 endpoints: > - 1 for SSTX1+SSRX1 (A2,A3 + B10,B11) > - 1 for SSTX2+SSRX2 (B2,B3 + A10, A11) > > A device tree for this would look as follows: > > // Type-C port driver > ec { > ... > cros_ec_typec { > ... > usb-c0 { > compatible = "usb-c-connector"; > ports { > hs : port@0 { > ... > }; > ss: port@1 { > reg = <1>; > c0_sstrx1: endpoint@0 { > reg = <0>; > remote-endpoint = <&anx7625_out0>; > }; > c0_sstrx2: endpoint@0 { > reg = <0>; > remote-endpoint = <&usb3hub_out0>; > }; > }; > sbu : port@2 { > ... > }; > }; > }; > usb-c1 { > compatible = "usb-c-connector"; > ports { > hs : port@0 { > ... > }; > ss: port@1 { > reg = <1>; > c1_sstrx1: endpoint@0 { > reg = <0>; > remote-endpoint = <&anx7625_out1>; > }; > c1_sstrx2: endpoint@0 { > reg = <0>; > remote-endpoint = <&usb3hub_out1>; > }; > }; > sbu : port@2 { > ... > }; > }; > }; > }; > }; > > // DRM bridge / Type-C mode switch > anx_bridge: anx7625@58 { > compatible = "analogix,anx7625"; > reg = <0x58>; > ... > // Input from DP controller > port@0 { > reg = <0>; > ... > }; > > // Output to Type-C connector / DP panel > port@1 { > reg = <1>; > > anx7625_out0: endpoint@0 { > reg = <0>; > mode-switch; > remote-endpoint = <&c0_sstrx1>; > }; > anx7625_out1: endpoint@1 { > reg = <1>; > mode-switch; > remote-endpoint = <&c1_sstrx1>; > }; > }; > }; > > // USB3 hub > usb3hub: foo_hub { > ... > ports@0 { > // End point connected to USB3 host controller on SOC. > }; > port@1 { > reg = <1>; > > foo_hub_out0: endpoint@0 { > reg = <0>; > mode-switch; ---> See c.) later > remote-endpoint = <&c0_sstrx2>; > }; > foo_hub_out1: endpoint@1 { > reg = <1>; > mode-switch; > remote-endpoint = <&c1_sstrx2>; > }; > }; > }; > > Notes: > - On the Chrome OS platform, the USB3 Hub is controlled by > the EC, so we don't really need to describe that connection, > but I've added a minimal one here just to show how the graph > connection would work if the HUB was controlled by the SoC. > - The above assumes that other hardware is controlling orientation. > We can add "orientation-switch" drivers along the graph path > if there is other hardware which controls orientation. > > Example 2: 1 USB-C connector connected to 1 drm-bridge/ mode-switch > > I've tried to use Bjorn's example [1], but I might have made > some mistakes since I don't have access to the schematic. > > > SoC > +------------------------------------------+ > | | > | +---------------+ | > | | | | > | | DP ctrllr | +---------+ | C0 > | | +-------+ | | 2 lane +----------+ > | +---------------+ | QMP +-----+-----/--------+ SSTRX1 | > | | PHY | | | | > | +-------------+ 2 lane | | | 2 lane | | > | | +----/----+ +-----+-----/--------+ SSTRX2 | > | | dwc3 | +---------+ | | | > | | | | | | > | | | +---------+ | | | > | | +---------+ HS PHY | | HS lanes | | > | +-------------+ | +-----+----/---------+ D +/- | > | | | | +----------+ > | +---------+ | > | | > +------------------------------------------+ > > The DT would look something like this (borrowing from Stephen's example [2]): > > qmp { > mode-switch; ----> See b.) later. > orientation-switch; > ports { > qmp_usb_in: port@0 { > reg = <0>; > remote-endpoint = <&usb3_phy_out>; > }; > qmp_dp_in: port@1 { > reg = <1>; > remote-endpoint = <&dp_phy_out>; > }; > port@2 { > reg = <2>; > qmp_usb_dp_out0: endpoint@0 { > reg = <0>; > remote-endpoint = <&c0_sstrx1>; > }; > qmp_usb_dp_out1: endpoint@1 { > reg = <1>; > remote-endpoint = <&c0_sstrx2>; > }; > }; > }; > > dp-phy { > ports { > dp_phy_out: port { > remote-endpoint = <&qmp_dp_in>; > }; > }; > }; > > dwc3: usb-phy { > ports { > usb3_phy_out: port@0 { > reg = <0>; > remote-endpoint = <&qmp_usb_in>; > }; > }; > }; > > glink { > c0: usb-c-connector { > compatible = "usb-c-connector"; > ports { > hs: port@0 { > reg = <0>; > endpoint@0 { > reg = <0>; > remote-endpoint = <&hs_phy_out>; > }; > }; > > ss: port@1 { > reg = <1>; > c0_sstrx1: endpoint@0 { > reg = <0>; > remote-endpoint = <&qmp_usb_dp_out0>; > }; > c0_sstrx2: endpoint@1 { > reg = <1>; > remote-endpoint = <&qmp_usb_dp_out1>; > }; > }; > }; > }; > }; > > Notes: > a. This proposal doesn't deal with the DRM bridge HPD forwarding; I > believe that is covered by Stephen's example/proposal in [2], and > can be addressed separately. That said, this binding is compatible > with the proposal in [2], that is, make the "mode-switch" driver a > drm-bridge and forward the HPD info to the upstream DRM-bridge (DP controller). > The driver implementing "mode-switch" will be able to do that, since > it gets DP status/attention VDOS with HPD info from the Type-C port driver. > b. If both SSTRX pairs from a connector are routed to the same > hardware block (example 2) then the device would keep "mode-switch" > as a top level property (and the fwnode associated with "mode-switch" > is the drm-bridge device). > c. If SSTRX pairs from 2 connectors are routed to the same > hardware block (example 1), then each end-point which is connected to > the USB-C connector will have a "mode-switch" property in its end-point. > There will be 2 mode switches registered here, and the fwnode for each > "mode-switch" is the end-point node. > > b.) and c.) can be handled by Type C mux registration and matching > code. We already have 3 mux devs for each mux [3]. > > For the single mode-switch case, mux_dev[1] will just refer to the top-level > mode-switch registered by the DRM bridge / switch driver (example 1). > For the 2 mode-switch case, typec_mux_dev[1] will have 2 child > typec_mux_dev's, each of which represents the mode-switches > registered by the DRM bridge / switch driver. Introducing this > indirection means the port driver / alternate mode driver don't > need to care about how the connectors are routed; the framework > will just call the mux_set() function on the mux_dev() or its > children if it has any. > > The benefit of this approach is existing bindings (which just > assume 1 endpoint from usb-c-connector/port@1) should continue to > work without any changes. > > Why don't we use data lanes for the usb-c-connector > endpoints? I guess we could, but I am not a fan of adding the > extra data-lane parsing logic to the Type-C framework (I > don't think drivers need that level of detail from the connector > binding). And even then, we will still need an extra end-point > if the lanes of the USB-C connector are routed to different hardware blocks. > > The Type-C connector spec doesn't specify any alternate modes > with < 1 SSTRX pair, so the most we can ever have (short of a > major change to the spec) is 2 SSTRX end points for a > connector each being routed to different hardware blocks. > Codifying these as endpoint@0 and endpoint@1 in the usb-c-connector > binding seems to line up nicely with this detail of the spec. > > Thanks, > > -Prashant > > [1] https://lore.kernel.org/linux-usb/Yv1y9Wjp16CstJvK@baldur/ > [2] https://lore.kernel.org/linux-usb/CAE-0n52-QVeUVCB1qZzPbYyrb1drrbJf6H2DEEW9bOE6mh7egw@mail.gmail.com/ > [3] https://elixir.bootlin.com/linux/v6.0-rc3/source/drivers/usb/typec/mux.c#L259
Hi all, Are there any thoughts or comments about this proposal? On Sat, Sep 17, 2022 at 2:22 AM Prashant Malani <pmalani@chromium.org> wrote: > > Hi folks, > > On Fri, Sep 2, 2022 at 12:41 AM Prashant Malani <pmalani@chromium.org> wrote: > > > > Hi Rob, > > > > On Jul 12 11:45, Rob Herring wrote: > > > > > > That's not the right interpretation. There should not be some Type-C > > > specific child mux/switch node because the device has no such h/w within > > > it. Assuming all the possibilities Stephen outlined are valid, it's > > > clear this lane selection has nothing to do with Type-C. It does have an > > > output port for its DP output already and using that to describe the > > > connection to DP connector(s) and/or Type-C connector(s) should be > > > handled. > > > Rob > > > > Below I've listed the proposal binding (for the Type-C connector) along > > with 2 sample hardware diagrams and corresponding DT. > > Any thoughts about this proposal? > > > > > The updated binding in usb-c-connector would be as follows: > > > > diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml > > index ae515651fc6b..a043b09cb8ec 100644 > > --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml > > +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml > > @@ -183,6 +183,30 @@ properties: > > port@1: > > $ref: /schemas/graph.yaml#/properties/port > > description: Super Speed (SS), present in SS capable connectors. > > + properties: > > + '#address-cells': > > + const: 1 > > + > > + '#size-cells': > > + const: 0 > > + > > + patternProperties: > > + "^endpoint@[0-1]$": > > + $ref: /schemas/graph.yaml#/$defs/endpoint-base > > + description: > > + Endpoints for the two SS lanes. endpoint@0 refers to SSTRX1 (A2,A3,B10,B11) > > + and endpoint@1 refers to SSTRX2 (B2,B3,A10,A11). > > + additionalProperties: false > > + > > + properties: > > + reg: > > + maxItems: 1 > > + > > + remote-endpoint: true > > + > > + required: > > + - reg > > + - remote-endpoint > > > > port@2: > > $ref: /schemas/graph.yaml#/properties/port > > > > Here are 2 examples of how that would look on some existing hardware: > > > > Example 1. 2 usb-c-connectors connecting to 1 drm bridge / DP switch: > > > > Here is the diagram we are using on the MTK platform: > > > > SOC > > +---------------------+ C0 > > | | +----------+ 2 lane +--------+ > > | | | +---------/---------+ SSTRX1 | > > | | | | | | > > | MIPI DPI | | | 2 lane | | > > | +------------+ ANX 7625 +---/-----+ +----+ SSTRX2 | > > | | | | | | +--------+ > > | | +----------+ | | > > +---------------------+ | | > > | | +----------+ 2 lane | | C1 > > | | | +----/----C----+ +--------+ > > | USB3 HC | 2 lane | | | | SSTRX1 | > > | +-----/------+ USB3 HUB | +---------+ | > > | (host controller) | | | 2 lane | | > > | | | +---------/---------+ SSTRX2 | > > +---------------------+ | | | | > > +----------+ +--------+ > > > > Some platforms use it6505, so that can be swapped in for anx7625 > > without any change to the rest of the hardware diagram. > > > > From the above, we can see that it is helpful to describe the > > Type-C SS lines as 2 endpoints: > > - 1 for SSTX1+SSRX1 (A2,A3 + B10,B11) > > - 1 for SSTX2+SSRX2 (B2,B3 + A10, A11) > > > > A device tree for this would look as follows: > > > > // Type-C port driver > > ec { > > ... > > cros_ec_typec { > > ... > > usb-c0 { > > compatible = "usb-c-connector"; > > ports { > > hs : port@0 { > > ... > > }; > > ss: port@1 { > > reg = <1>; > > c0_sstrx1: endpoint@0 { > > reg = <0>; > > remote-endpoint = <&anx7625_out0>; > > }; > > c0_sstrx2: endpoint@0 { > > reg = <0>; > > remote-endpoint = <&usb3hub_out0>; > > }; > > }; > > sbu : port@2 { > > ... > > }; > > }; > > }; > > usb-c1 { > > compatible = "usb-c-connector"; > > ports { > > hs : port@0 { > > ... > > }; > > ss: port@1 { > > reg = <1>; > > c1_sstrx1: endpoint@0 { > > reg = <0>; > > remote-endpoint = <&anx7625_out1>; > > }; > > c1_sstrx2: endpoint@0 { > > reg = <0>; > > remote-endpoint = <&usb3hub_out1>; > > }; > > }; > > sbu : port@2 { > > ... > > }; > > }; > > }; > > }; > > }; > > > > // DRM bridge / Type-C mode switch > > anx_bridge: anx7625@58 { > > compatible = "analogix,anx7625"; > > reg = <0x58>; > > ... > > // Input from DP controller > > port@0 { > > reg = <0>; > > ... > > }; > > > > // Output to Type-C connector / DP panel > > port@1 { > > reg = <1>; > > > > anx7625_out0: endpoint@0 { > > reg = <0>; > > mode-switch; > > remote-endpoint = <&c0_sstrx1>; > > }; > > anx7625_out1: endpoint@1 { > > reg = <1>; > > mode-switch; > > remote-endpoint = <&c1_sstrx1>; > > }; > > }; > > }; > > > > // USB3 hub > > usb3hub: foo_hub { > > ... > > ports@0 { > > // End point connected to USB3 host controller on SOC. > > }; > > port@1 { > > reg = <1>; > > > > foo_hub_out0: endpoint@0 { > > reg = <0>; > > mode-switch; ---> See c.) later > > remote-endpoint = <&c0_sstrx2>; > > }; > > foo_hub_out1: endpoint@1 { > > reg = <1>; > > mode-switch; > > remote-endpoint = <&c1_sstrx2>; > > }; > > }; > > }; > > > > Notes: > > - On the Chrome OS platform, the USB3 Hub is controlled by > > the EC, so we don't really need to describe that connection, > > but I've added a minimal one here just to show how the graph > > connection would work if the HUB was controlled by the SoC. > > - The above assumes that other hardware is controlling orientation. > > We can add "orientation-switch" drivers along the graph path > > if there is other hardware which controls orientation. > > > > Example 2: 1 USB-C connector connected to 1 drm-bridge/ mode-switch > > > > I've tried to use Bjorn's example [1], but I might have made > > some mistakes since I don't have access to the schematic. > > > > > > SoC > > +------------------------------------------+ > > | | > > | +---------------+ | > > | | | | > > | | DP ctrllr | +---------+ | C0 > > | | +-------+ | | 2 lane +----------+ > > | +---------------+ | QMP +-----+-----/--------+ SSTRX1 | > > | | PHY | | | | > > | +-------------+ 2 lane | | | 2 lane | | > > | | +----/----+ +-----+-----/--------+ SSTRX2 | > > | | dwc3 | +---------+ | | | > > | | | | | | > > | | | +---------+ | | | > > | | +---------+ HS PHY | | HS lanes | | > > | +-------------+ | +-----+----/---------+ D +/- | > > | | | | +----------+ > > | +---------+ | > > | | > > +------------------------------------------+ > > > > The DT would look something like this (borrowing from Stephen's example [2]): > > > > qmp { > > mode-switch; ----> See b.) later. > > orientation-switch; > > ports { > > qmp_usb_in: port@0 { > > reg = <0>; > > remote-endpoint = <&usb3_phy_out>; > > }; > > qmp_dp_in: port@1 { > > reg = <1>; > > remote-endpoint = <&dp_phy_out>; > > }; > > port@2 { > > reg = <2>; > > qmp_usb_dp_out0: endpoint@0 { > > reg = <0>; > > remote-endpoint = <&c0_sstrx1>; > > }; > > qmp_usb_dp_out1: endpoint@1 { > > reg = <1>; > > remote-endpoint = <&c0_sstrx2>; > > }; > > }; > > }; > > > > dp-phy { > > ports { > > dp_phy_out: port { > > remote-endpoint = <&qmp_dp_in>; > > }; > > }; > > }; > > > > dwc3: usb-phy { > > ports { > > usb3_phy_out: port@0 { > > reg = <0>; > > remote-endpoint = <&qmp_usb_in>; > > }; > > }; > > }; > > > > glink { > > c0: usb-c-connector { > > compatible = "usb-c-connector"; > > ports { > > hs: port@0 { > > reg = <0>; > > endpoint@0 { > > reg = <0>; > > remote-endpoint = <&hs_phy_out>; > > }; > > }; > > > > ss: port@1 { > > reg = <1>; > > c0_sstrx1: endpoint@0 { > > reg = <0>; > > remote-endpoint = <&qmp_usb_dp_out0>; > > }; > > c0_sstrx2: endpoint@1 { > > reg = <1>; > > remote-endpoint = <&qmp_usb_dp_out1>; > > }; > > }; > > }; > > }; > > }; > > > > Notes: > > a. This proposal doesn't deal with the DRM bridge HPD forwarding; I > > believe that is covered by Stephen's example/proposal in [2], and > > can be addressed separately. That said, this binding is compatible > > with the proposal in [2], that is, make the "mode-switch" driver a > > drm-bridge and forward the HPD info to the upstream DRM-bridge (DP controller). > > The driver implementing "mode-switch" will be able to do that, since > > it gets DP status/attention VDOS with HPD info from the Type-C port driver. > > b. If both SSTRX pairs from a connector are routed to the same > > hardware block (example 2) then the device would keep "mode-switch" > > as a top level property (and the fwnode associated with "mode-switch" > > is the drm-bridge device). > > c. If SSTRX pairs from 2 connectors are routed to the same > > hardware block (example 1), then each end-point which is connected to > > the USB-C connector will have a "mode-switch" property in its end-point. > > There will be 2 mode switches registered here, and the fwnode for each > > "mode-switch" is the end-point node. > > > > b.) and c.) can be handled by Type C mux registration and matching > > code. We already have 3 mux devs for each mux [3]. > > > > For the single mode-switch case, mux_dev[1] will just refer to the top-level > > mode-switch registered by the DRM bridge / switch driver (example 1). > > For the 2 mode-switch case, typec_mux_dev[1] will have 2 child > > typec_mux_dev's, each of which represents the mode-switches > > registered by the DRM bridge / switch driver. Introducing this > > indirection means the port driver / alternate mode driver don't > > need to care about how the connectors are routed; the framework > > will just call the mux_set() function on the mux_dev() or its > > children if it has any. > > > > The benefit of this approach is existing bindings (which just > > assume 1 endpoint from usb-c-connector/port@1) should continue to > > work without any changes. > > > > Why don't we use data lanes for the usb-c-connector > > endpoints? I guess we could, but I am not a fan of adding the > > extra data-lane parsing logic to the Type-C framework (I > > don't think drivers need that level of detail from the connector > > binding). And even then, we will still need an extra end-point > > if the lanes of the USB-C connector are routed to different hardware blocks. > > > > The Type-C connector spec doesn't specify any alternate modes > > with < 1 SSTRX pair, so the most we can ever have (short of a > > major change to the spec) is 2 SSTRX end points for a > > connector each being routed to different hardware blocks. > > Codifying these as endpoint@0 and endpoint@1 in the usb-c-connector > > binding seems to line up nicely with this detail of the spec. > > > > Thanks, > > > > -Prashant > > > > [1] https://lore.kernel.org/linux-usb/Yv1y9Wjp16CstJvK@baldur/ > > [2] https://lore.kernel.org/linux-usb/CAE-0n52-QVeUVCB1qZzPbYyrb1drrbJf6H2DEEW9bOE6mh7egw@mail.gmail.com/ > > [3] https://elixir.bootlin.com/linux/v6.0-rc3/source/drivers/usb/typec/mux.c#L259
diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml new file mode 100644 index 000000000000..78b0190c8543 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: USB Type-C Switch + +maintainers: + - Prashant Malani <pmalani@chromium.org> + +description: + A USB Type-C switch represents a component which routes USB Type-C data + lines to various protocol host controllers (e.g USB, VESA DisplayPort, + Thunderbolt etc.) depending on which mode the Type-C port, port partner + and cable are operating in. It can also modify lane routing based on + the orientation of a connected Type-C peripheral. + +properties: + compatible: + const: typec-switch + + mode-switch: + type: boolean + description: Specify that this switch can handle alternate mode switching. + + orientation-switch: + type: boolean + description: Specify that this switch can handle orientation switching. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: OF graph binding modelling data lines to the Type-C switch. + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Link between the switch and a Type-C connector. + + required: + - port@0 + +required: + - compatible + - ports + +anyOf: + - required: + - mode-switch + - required: + - orientation-switch + +additionalProperties: true + +examples: + - | + drm-bridge { + usb-switch { + compatible = "typec-switch"; + mode-switch; + orientation-switch; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + anx_ep: endpoint { + remote-endpoint = <&typec_controller>; + }; + }; + }; + }; + };