All of lore.kernel.org
 help / color / mirror / Atom feed
* USB role switches, usb-connector, typec and device trees
@ 2018-06-06 21:36 ` Mats Karrman
  2018-06-07  7:22   ` Hans de Goede
  2018-06-07 11:40   ` Andrzej Hajda
  0 siblings, 2 replies; 11+ messages in thread
From: Mats Karrman @ 2018-06-06 21:36 UTC (permalink / raw)
  To: Heikki Krogerus, Hans de Goede, Andrzej Hajda
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

Hello Gentlemen,

I'm trying to get my head around USB role switches in connection with Type-C ports
and device-trees. So far I have not found much documentation, e.g. there are no
device-tree bindings documented and really no good examples in existing device
trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
you a couple of questions instead:

1) tcpm uses the port device struct to find a single usb_role_switch but there is
room for three USB busses in the Type-C connector; one high speed and two (?) super-
speed. These would not all come from the same controller (there might even be
separate controllers for host and device mode for each bus).
The case I am working on now only have a single USB2 otg controller so it should
be possible to make that driver register a role switch but for other cases?
I imagine it would be possible to create a composite driver as a proxy for all role
switches but that would probably be different for every platform/product - not
very elegant. Could the role switch infrastructure be extended to handle arbitrary
sets of coordinated switches?

2) How should the connection between the Type-C port and the switches best be
expressed in a device tree? Using graph I presume, but should it be mixed into the
existing "usb-connector" or should this be a separate block?
I think it is unfortunate that the graph use numeric addresses that need to be
fixed by documentation and already I see problems with the current assignment
(0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
controllers. Graph do support multiple endpoints for one port but then we have
another level of magic numbers which does not exactly make things easier
(e.g. 0=dual or host controller, 1=device controller, 2=mode switch).

What are your thoughts on this? Please tell me I missed something and that there is
a simple solution :-)

BR // Mats

[1] https://www.spinics.net/lists/linux-usb/msg168071.html
[2] https://www.spinics.net/lists/linux-usb/msg168072.html


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-06 21:36 ` USB role switches, usb-connector, typec and device trees Mats Karrman
@ 2018-06-07  7:22   ` Hans de Goede
  2018-06-07 12:01     ` Heikki Krogerus
  2018-06-07 11:40   ` Andrzej Hajda
  1 sibling, 1 reply; 11+ messages in thread
From: Hans de Goede @ 2018-06-07  7:22 UTC (permalink / raw)
  To: Mats Karrman, Heikki Krogerus, Andrzej Hajda
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

Hi,

On 06-06-18 23:36, Mats Karrman wrote:
> Hello Gentlemen,
> 
> I'm trying to get my head around USB role switches in connection with Type-C ports
> and device-trees. So far I have not found much documentation, e.g. there are no
> device-tree bindings documented and really no good examples in existing device
> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
> you a couple of questions instead:
> 
> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
> room for three USB busses in the Type-C connector; one high speed and two (?) super-
> speed. These would not all come from the same controller (there might even be
> separate controllers for host and device mode for each bus).

AFAIK the 2nd superspeed USB bus is never used as such. There really is only 1
USB bus on the Type-C connector, the combined USB-2 + the 1st superspeed bus,
physically these are 2 separate busses but that is purely for compatibility
reasons, logically there really only is 1 bus, just like a superspeed Type-A
connector has both busses physically but logically represents a single bus/port.

> The case I am working on now only have a single USB2 otg controller so it should
> be possible to make that driver register a role switch but for other cases?

I guess theoretically a device could use separate role switches / muxes for
the USB-2 and USB-3 busses, but that would be weird. So lets cross that bridge
when we reach it.

> I imagine it would be possible to create a composite driver as a proxy for all role
> switches but that would probably be different for every platform/product - not
> very elegant. Could the role switch infrastructure be extended to handle arbitrary
> sets of coordinated switches?

As said lets cross that bridge when we reach it.

> 2) How should the connection between the Type-C port and the switches best be
> expressed in a device tree? Using graph I presume, but should it be mixed into the
> existing "usb-connector" or should this be a separate block?
> I think it is unfortunate that the graph use numeric addresses that need to be
> fixed by documentation and already I see problems with the current assignment
> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
> controllers. Graph do support multiple endpoints for one port but then we have
> another level of magic numbers which does not exactly make things easier
> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).

The graph stuff is more Heikki's specialty so I will let Heikki answer this.

Regards,

Hans


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-06 21:36 ` USB role switches, usb-connector, typec and device trees Mats Karrman
  2018-06-07  7:22   ` Hans de Goede
@ 2018-06-07 11:40   ` Andrzej Hajda
  2018-06-12 17:33     ` Mats Karrman
  1 sibling, 1 reply; 11+ messages in thread
From: Andrzej Hajda @ 2018-06-07 11:40 UTC (permalink / raw)
  To: Mats Karrman, Heikki Krogerus, Hans de Goede
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

On 06.06.2018 23:36, Mats Karrman wrote:
> Hello Gentlemen,
>
> I'm trying to get my head around USB role switches in connection with Type-C ports
> and device-trees. So far I have not found much documentation, e.g. there are no
> device-tree bindings documented and really no good examples in existing device
> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
> you a couple of questions instead:
>
> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
> room for three USB busses in the Type-C connector; one high speed and two (?) super-
> speed. These would not all come from the same controller (there might even be
> separate controllers for host and device mode for each bus).
> The case I am working on now only have a single USB2 otg controller so it should
> be possible to make that driver register a role switch but for other cases?
> I imagine it would be possible to create a composite driver as a proxy for all role
> switches but that would probably be different for every platform/product - not
> very elegant. Could the role switch infrastructure be extended to handle arbitrary
> sets of coordinated switches?
>
> 2) How should the connection between the Type-C port and the switches best be
> expressed in a device tree? Using graph I presume, but should it be mixed into the
> existing "usb-connector" or should this be a separate block?
> I think it is unfortunate that the graph use numeric addresses that need to be
> fixed by documentation 

I also do not like port numbers, I even have argued for using names
during multiple discussions, but the discussion ended as is :(

> and already I see problems with the current assignment
> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
> controllers. Graph do support multiple endpoints for one port but then we have
> another level of magic numbers which does not exactly make things easier
> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).

Where do you want to use these magic numbers? To describe endpoints? I
guess there should be controllable mux/switch behind the port, it could
be standalone, or a part of bigger IP.
Anyway it should be described by device node, probably parent of USB-C
device-node, in such case only links from USB connector going to
different IPs should be described using OF graphs.
And in such case drivers of these devices should
ask/determine/change/communicate their role using in-kernel frameworks
(for example extcon).

There are many different configurations of USB-C ports
InterfaceControllers, Muxes/Switches, USB related devices, Alternate
Mode devices, PMICs, USB-PDs, ....
Could you describe particular one you have problem with, to make the
discussion more specific.

Regards
Andrzej

>
> What are your thoughts on this? Please tell me I missed something and that there is
> a simple solution :-)






>
> BR // Mats
>
> [1] https://www.spinics.net/lists/linux-usb/msg168071.html
> [2] https://www.spinics.net/lists/linux-usb/msg168072.html
>
>
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-07  7:22   ` Hans de Goede
@ 2018-06-07 12:01     ` Heikki Krogerus
  2018-06-12 17:16       ` Mats Karrman
  0 siblings, 1 reply; 11+ messages in thread
From: Heikki Krogerus @ 2018-06-07 12:01 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mats Karrman, Andrzej Hajda, Greg Kroah-Hartman, linux-usb, devicetree

On Thu, Jun 07, 2018 at 09:22:56AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 06-06-18 23:36, Mats Karrman wrote:
> > Hello Gentlemen,
> > 
> > I'm trying to get my head around USB role switches in connection with Type-C ports
> > and device-trees. So far I have not found much documentation, e.g. there are no
> > device-tree bindings documented and really no good examples in existing device
> > trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
> > you a couple of questions instead:
> > 
> > 1) tcpm uses the port device struct to find a single usb_role_switch but there is
> > room for three USB busses in the Type-C connector; one high speed and two (?) super-
> > speed. These would not all come from the same controller (there might even be
> > separate controllers for host and device mode for each bus).

I believe USB 3.2 spec in practice says that the two superspeed
"lanes" must to go to the same controller. Only one will be used for
link training etc. The second one is pulled in after certain state of
enumeration has been passed.

So we may theoretically have two controllers to deal with, one for
USB2 and another for USB3, but not three.

But in any case, let's not try to fix theoretical problems that may
never exist.

> AFAIK the 2nd superspeed USB bus is never used as such. There really is only 1
> USB bus on the Type-C connector, the combined USB-2 + the 1st superspeed bus,
> physically these are 2 separate busses but that is purely for compatibility
> reasons, logically there really only is 1 bus, just like a superspeed Type-A
> connector has both busses physically but logically represents a single bus/port.
> 
> > The case I am working on now only have a single USB2 otg controller so it should
> > be possible to make that driver register a role switch but for other cases?
> 
> I guess theoretically a device could use separate role switches / muxes for
> the USB-2 and USB-3 busses, but that would be weird. So lets cross that bridge
> when we reach it.
> 
> > I imagine it would be possible to create a composite driver as a proxy for all role
> > switches but that would probably be different for every platform/product - not
> > very elegant. Could the role switch infrastructure be extended to handle arbitrary
> > sets of coordinated switches?
> 
> As said lets cross that bridge when we reach it.

Agreed.

> > 2) How should the connection between the Type-C port and the switches best be
> > expressed in a device tree? Using graph I presume, but should it be mixed into the
> > existing "usb-connector" or should this be a separate block?

I don't know?

I'm not super comfortable proposing things for these bindings because
my knowledge of DT is a bit limited. I mostly work with ACPI based
platforms.

I'm not even completely sure device graph is usable in our case,
though I pretty sure it is.

> > I think it is unfortunate that the graph use numeric addresses that need to be
> > fixed by documentation and already I see problems with the current assignment
> > (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
> > controllers. Graph do support multiple endpoints for one port but then we have
> > another level of magic numbers which does not exactly make things easier
> > (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
> 
> The graph stuff is more Heikki's specialty so I will let Heikki answer this.

I'm not really a graph expert. It is just the only tool in kernel I
can see that allows us to link together all these different components
in HW description, and which has support for both DT and ACPI in Linux
kernel. That is the only reason I've talked about it.

One of the motivations for the device connection API was that it hides
the actual method these components are linked together in HW
description. What ever the method is, device graph or something else
(we can support different ways), the drivers don't need to know about
it.

But in any case, I don't understand why should we depend on the
addresses (index in practice) in this case? We can define an extra
identifier property. Then in code we can walk through the whole graph,
ignoring the address, and checking every remote endpoint in it and use
that property to find what we are looking for, no? I'm pretty sure
somebody already proposed "type" property for that "usb-connector"
and I understood it was meant for identifying the endpoint (maybe I'm
wrong), but I guess it newer went in?


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-07 12:01     ` Heikki Krogerus
@ 2018-06-12 17:16       ` Mats Karrman
  2018-06-13 13:51         ` Heikki Krogerus
  0 siblings, 1 reply; 11+ messages in thread
From: Mats Karrman @ 2018-06-12 17:16 UTC (permalink / raw)
  To: Heikki Krogerus, Hans de Goede
  Cc: Andrzej Hajda, Greg Kroah-Hartman, linux-usb, devicetree

On 2018-06-07 14:01, Heikki Krogerus wrote:

> On Thu, Jun 07, 2018 at 09:22:56AM +0200, Hans de Goede wrote:
>> Hi,
>>
>> On 06-06-18 23:36, Mats Karrman wrote:
>>> Hello Gentlemen,
>>>
>>> I'm trying to get my head around USB role switches in connection with Type-C ports
>>> and device-trees. So far I have not found much documentation, e.g. there are no
>>> device-tree bindings documented and really no good examples in existing device
>>> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
>>> you a couple of questions instead:
>>>
>>> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
>>> room for three USB busses in the Type-C connector; one high speed and two (?) super-
>>> speed. These would not all come from the same controller (there might even be
>>> separate controllers for host and device mode for each bus).
> I believe USB 3.2 spec in practice says that the two superspeed
> "lanes" must to go to the same controller. Only one will be used for
> link training etc. The second one is pulled in after certain state of
> enumeration has been passed.
>
> So we may theoretically have two controllers to deal with, one for
> USB2 and another for USB3, but not three.
>
> But in any case, let's not try to fix theoretical problems that may
> never exist.
>
>> AFAIK the 2nd superspeed USB bus is never used as such. There really is only 1
>> USB bus on the Type-C connector, the combined USB-2 + the 1st superspeed bus,
>> physically these are 2 separate busses but that is purely for compatibility
>> reasons, logically there really only is 1 bus, just like a superspeed Type-A
>> connector has both busses physically but logically represents a single bus/port.
>>
>>> The case I am working on now only have a single USB2 otg controller so it should
>>> be possible to make that driver register a role switch but for other cases?
>> I guess theoretically a device could use separate role switches / muxes for
>> the USB-2 and USB-3 busses, but that would be weird. So lets cross that bridge
>> when we reach it.
>>
>>> I imagine it would be possible to create a composite driver as a proxy for all role
>>> switches but that would probably be different for every platform/product - not
>>> very elegant. Could the role switch infrastructure be extended to handle arbitrary
>>> sets of coordinated switches?
>> As said lets cross that bridge when we reach it.
> Agreed.

OK, I'm buying what you're saying. After reading some manuals for USB3 controllers
and USB3 equipped SoC's I realize that most USB3 controllers seem to also support
USB2. Makes things easier, although not as flexible as I imagined.
One thing that led me astray was the comment for usb_role_switch_register() and the
separate device struct pointers for usb2/usb3/udc in the usb_role_switch_desc struct.
Still not totally clear to me what they are for?

>>> 2) How should the connection between the Type-C port and the switches best be
>>> expressed in a device tree? Using graph I presume, but should it be mixed into the
>>> existing "usb-connector" or should this be a separate block?
> I don't know?
>
> I'm not super comfortable proposing things for these bindings because
> my knowledge of DT is a bit limited. I mostly work with ACPI based
> platforms.
>
> I'm not even completely sure device graph is usable in our case,
> though I pretty sure it is.
>
>>> I think it is unfortunate that the graph use numeric addresses that need to be
>>> fixed by documentation and already I see problems with the current assignment
>>> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
>>> controllers. Graph do support multiple endpoints for one port but then we have
>>> another level of magic numbers which does not exactly make things easier
>>> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
>> The graph stuff is more Heikki's specialty so I will let Heikki answer this.
> I'm not really a graph expert. It is just the only tool in kernel I
> can see that allows us to link together all these different components
> in HW description, and which has support for both DT and ACPI in Linux
> kernel. That is the only reason I've talked about it.
>
> One of the motivations for the device connection API was that it hides
> the actual method these components are linked together in HW
> description. What ever the method is, device graph or something else
> (we can support different ways), the drivers don't need to know about
> it.

Ahh, this is complicated and the lack of examples makes it a bit hard to
digest. Is it your expectation that the OF graph parsing code will be calling
device_connection_add() for every graph connection found in the device
tree or maybe for every connection with an "id" property?
(Ugh, just realized that the "reg" numeric value of the endpoint node is
put in the "id" field of the endpoint struct, bad luck...).

// Mats

> But in any case, I don't understand why should we depend on the
> addresses (index in practice) in this case? We can define an extra
> identifier property. Then in code we can walk through the whole graph,
> ignoring the address, and checking every remote endpoint in it and use
> that property to find what we are looking for, no? I'm pretty sure
> somebody already proposed "type" property for that "usb-connector"
> and I understood it was meant for identifying the endpoint (maybe I'm
> wrong), but I guess it newer went in?
>
> Thanks,

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-07 11:40   ` Andrzej Hajda
@ 2018-06-12 17:33     ` Mats Karrman
  2018-06-13  7:06       ` Andrzej Hajda
  0 siblings, 1 reply; 11+ messages in thread
From: Mats Karrman @ 2018-06-12 17:33 UTC (permalink / raw)
  To: Andrzej Hajda, Heikki Krogerus, Hans de Goede
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

Hi Andrzej,

On 2018-06-07 13:40, Andrzej Hajda wrote:

> On 06.06.2018 23:36, Mats Karrman wrote:
>> Hello Gentlemen,
>>
>> I'm trying to get my head around USB role switches in connection with Type-C ports
>> and device-trees. So far I have not found much documentation, e.g. there are no
>> device-tree bindings documented and really no good examples in existing device
>> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
>> you a couple of questions instead:
>>
>> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
>> room for three USB busses in the Type-C connector; one high speed and two (?) super-
>> speed. These would not all come from the same controller (there might even be
>> separate controllers for host and device mode for each bus).
>> The case I am working on now only have a single USB2 otg controller so it should
>> be possible to make that driver register a role switch but for other cases?
>> I imagine it would be possible to create a composite driver as a proxy for all role
>> switches but that would probably be different for every platform/product - not
>> very elegant. Could the role switch infrastructure be extended to handle arbitrary
>> sets of coordinated switches?
>>
>> 2) How should the connection between the Type-C port and the switches best be
>> expressed in a device tree? Using graph I presume, but should it be mixed into the
>> existing "usb-connector" or should this be a separate block?
>> I think it is unfortunate that the graph use numeric addresses that need to be
>> fixed by documentation
> I also do not like port numbers, I even have argued for using names
> during multiple discussions, but the discussion ended as is :(
>
>> and already I see problems with the current assignment
>> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
>> controllers. Graph do support multiple endpoints for one port but then we have
>> another level of magic numbers which does not exactly make things easier
>> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
> Where do you want to use these magic numbers? To describe endpoints? I

For some hypothetic worst case scenario where a switch needs to handle
different USB controllers for port host and device mode. However I think
Heikki and Hans are correct in saying we should wait to worry about that
until we have an actual use-case.

> guess there should be controllable mux/switch behind the port, it could
> be standalone, or a part of bigger IP.
> Anyway it should be described by device node, probably parent of USB-C

child?

> device-node, in such case only links from USB connector going to
> different IPs should be described using OF graphs.
> And in such case drivers of these devices should
> ask/determine/change/communicate their role using in-kernel frameworks
> (for example extcon).
>
> There are many different configurations of USB-C ports
> InterfaceControllers, Muxes/Switches, USB related devices, Alternate
> Mode devices, PMICs, USB-PDs, ....
> Could you describe particular one you have problem with, to make the
> discussion more specific.

My use-case now is simple. I have a typec port that I need to connect to
a dual-role USB controller, probably extended with a usb-role-switch
device and I want to express that connection in the device-tree. I was looking
for a documented description or example of how to do this but I realize that
that is not yet available.

// Mats


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-12 17:33     ` Mats Karrman
@ 2018-06-13  7:06       ` Andrzej Hajda
  2018-06-14 17:25         ` Mats Karrman
  0 siblings, 1 reply; 11+ messages in thread
From: Andrzej Hajda @ 2018-06-13  7:06 UTC (permalink / raw)
  To: Mats Karrman, Heikki Krogerus, Hans de Goede
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

On 12.06.2018 19:33, Mats Karrman wrote:
> Hi Andrzej,
>
> On 2018-06-07 13:40, Andrzej Hajda wrote:
>
>> On 06.06.2018 23:36, Mats Karrman wrote:
>>> Hello Gentlemen,
>>>
>>> I'm trying to get my head around USB role switches in connection with Type-C ports
>>> and device-trees. So far I have not found much documentation, e.g. there are no
>>> device-tree bindings documented and really no good examples in existing device
>>> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
>>> you a couple of questions instead:
>>>
>>> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
>>> room for three USB busses in the Type-C connector; one high speed and two (?) super-
>>> speed. These would not all come from the same controller (there might even be
>>> separate controllers for host and device mode for each bus).
>>> The case I am working on now only have a single USB2 otg controller so it should
>>> be possible to make that driver register a role switch but for other cases?
>>> I imagine it would be possible to create a composite driver as a proxy for all role
>>> switches but that would probably be different for every platform/product - not
>>> very elegant. Could the role switch infrastructure be extended to handle arbitrary
>>> sets of coordinated switches?
>>>
>>> 2) How should the connection between the Type-C port and the switches best be
>>> expressed in a device tree? Using graph I presume, but should it be mixed into the
>>> existing "usb-connector" or should this be a separate block?
>>> I think it is unfortunate that the graph use numeric addresses that need to be
>>> fixed by documentation
>> I also do not like port numbers, I even have argued for using names
>> during multiple discussions, but the discussion ended as is :(
>>
>>> and already I see problems with the current assignment
>>> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
>>> controllers. Graph do support multiple endpoints for one port but then we have
>>> another level of magic numbers which does not exactly make things easier
>>> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
>> Where do you want to use these magic numbers? To describe endpoints? I
> For some hypothetic worst case scenario where a switch needs to handle
> different USB controllers for port host and device mode. However I think
> Heikki and Hans are correct in saying we should wait to worry about that
> until we have an actual use-case.
>
>> guess there should be controllable mux/switch behind the port, it could
>> be standalone, or a part of bigger IP.
>> Anyway it should be described by device node, probably parent of USB-C
> child?
>
>> device-node, in such case only links from USB connector going to
>> different IPs should be described using OF graphs.
>> And in such case drivers of these devices should
>> ask/determine/change/communicate their role using in-kernel frameworks
>> (for example extcon).
>>
>> There are many different configurations of USB-C ports
>> InterfaceControllers, Muxes/Switches, USB related devices, Alternate
>> Mode devices, PMICs, USB-PDs, ....
>> Could you describe particular one you have problem with, to make the
>> discussion more specific.
> My use-case now is simple. I have a typec port that I need to connect to
> a dual-role USB controller, probably extended with a usb-role-switch
> device and I want to express that connection in the device-tree. I was looking
> for a documented description or example of how to do this but I realize that
> that is not yet available.

USB connector bindings [1] are not enough? Did you look at the example?
I do not know what is exactly your usb-role-switch. Can you provide some
schematics? Or describe which physical lines of USB-C connector are
connected to which chips (including muxes/switches).
Two rules of thumb, I think quite simple:
1. Do you have USB interface controller? Ie chip which is connected to
CC lines of USB-C and performs cable detection, maybe PD negotiations,
etc. This device should be the parent of USB connector node.
2. Connections between connector and other chips should be described
using OF graph.

[1]:
https://www.kernel.org/doc/Documentation/devicetree/bindings/connector/usb-connector.txt

Regards
Andrzej

>
> // Mats
>
>
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-12 17:16       ` Mats Karrman
@ 2018-06-13 13:51         ` Heikki Krogerus
  2018-06-15 21:51           ` Mats Karrman
  0 siblings, 1 reply; 11+ messages in thread
From: Heikki Krogerus @ 2018-06-13 13:51 UTC (permalink / raw)
  To: Mats Karrman
  Cc: Hans de Goede, Andrzej Hajda, Greg Kroah-Hartman, linux-usb, devicetree

On Tue, Jun 12, 2018 at 07:16:03PM +0200, Mats Karrman wrote:
> On 2018-06-07 14:01, Heikki Krogerus wrote:
> 
> > On Thu, Jun 07, 2018 at 09:22:56AM +0200, Hans de Goede wrote:
> > > Hi,
> > > 
> > > On 06-06-18 23:36, Mats Karrman wrote:
> > > > Hello Gentlemen,
> > > > 
> > > > I'm trying to get my head around USB role switches in connection with Type-C ports
> > > > and device-trees. So far I have not found much documentation, e.g. there are no
> > > > device-tree bindings documented and really no good examples in existing device
> > > > trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
> > > > you a couple of questions instead:
> > > > 
> > > > 1) tcpm uses the port device struct to find a single usb_role_switch but there is
> > > > room for three USB busses in the Type-C connector; one high speed and two (?) super-
> > > > speed. These would not all come from the same controller (there might even be
> > > > separate controllers for host and device mode for each bus).
> > I believe USB 3.2 spec in practice says that the two superspeed
> > "lanes" must to go to the same controller. Only one will be used for
> > link training etc. The second one is pulled in after certain state of
> > enumeration has been passed.
> > 
> > So we may theoretically have two controllers to deal with, one for
> > USB2 and another for USB3, but not three.
> > 
> > But in any case, let's not try to fix theoretical problems that may
> > never exist.
> > 
> > > AFAIK the 2nd superspeed USB bus is never used as such. There really is only 1
> > > USB bus on the Type-C connector, the combined USB-2 + the 1st superspeed bus,
> > > physically these are 2 separate busses but that is purely for compatibility
> > > reasons, logically there really only is 1 bus, just like a superspeed Type-A
> > > connector has both busses physically but logically represents a single bus/port.
> > > 
> > > > The case I am working on now only have a single USB2 otg controller so it should
> > > > be possible to make that driver register a role switch but for other cases?
> > > I guess theoretically a device could use separate role switches / muxes for
> > > the USB-2 and USB-3 busses, but that would be weird. So lets cross that bridge
> > > when we reach it.
> > > 
> > > > I imagine it would be possible to create a composite driver as a proxy for all role
> > > > switches but that would probably be different for every platform/product - not
> > > > very elegant. Could the role switch infrastructure be extended to handle arbitrary
> > > > sets of coordinated switches?
> > > As said lets cross that bridge when we reach it.
> > Agreed.
> 
> OK, I'm buying what you're saying. After reading some manuals for USB3 controllers
> and USB3 equipped SoC's I realize that most USB3 controllers seem to also support
> USB2. Makes things easier, although not as flexible as I imagined.
> One thing that led me astray was the comment for usb_role_switch_register() and the
> separate device struct pointers for usb2/usb3/udc in the usb_role_switch_desc struct.
> Still not totally clear to me what they are for?

They are not really used for anything. Well, not yet at least.

Even if there is only a single physical controller, in case of host,
there will be separate logical devices representing the USB2 bus the
USB3 bus. UDC is just UDC, the device is the physical controller.

I added those usb2/usb3/udc handles to the structure because a long
time a go somebody requested that we should have a way in user space
to see the USB buses we are dealing with somehow. So the idea was
never to actually use those in the code. That's why I'm talking about
symlinks in the TODO comment.

But if those are not useful, or confusing, I'm happy to drop them.

> > > > 2) How should the connection between the Type-C port and the switches best be
> > > > expressed in a device tree? Using graph I presume, but should it be mixed into the
> > > > existing "usb-connector" or should this be a separate block?
> > I don't know?
> > 
> > I'm not super comfortable proposing things for these bindings because
> > my knowledge of DT is a bit limited. I mostly work with ACPI based
> > platforms.
> > 
> > I'm not even completely sure device graph is usable in our case,
> > though I pretty sure it is.
> > 
> > > > I think it is unfortunate that the graph use numeric addresses that need to be
> > > > fixed by documentation and already I see problems with the current assignment
> > > > (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
> > > > controllers. Graph do support multiple endpoints for one port but then we have
> > > > another level of magic numbers which does not exactly make things easier
> > > > (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
> > > The graph stuff is more Heikki's specialty so I will let Heikki answer this.
> > I'm not really a graph expert. It is just the only tool in kernel I
> > can see that allows us to link together all these different components
> > in HW description, and which has support for both DT and ACPI in Linux
> > kernel. That is the only reason I've talked about it.
> > 
> > One of the motivations for the device connection API was that it hides
> > the actual method these components are linked together in HW
> > description. What ever the method is, device graph or something else
> > (we can support different ways), the drivers don't need to know about
> > it.
> 
> Ahh, this is complicated and the lack of examples makes it a bit hard to
> digest. Is it your expectation that the OF graph parsing code will be calling
> device_connection_add() for every graph connection found in the device
> tree or maybe for every connection with an "id" property?

No, the idea is that we parse the graph in
device_connection_find_match().

> (Ugh, just realized that the "reg" numeric value of the endpoint node is
> put in the "id" field of the endpoint struct, bad luck...).

Isn't the "compatible" property the one that should be used in this
case? The remote endpoint just has to have compatible property
matching the con_id, no?

My worry is that currently there is no function to convert a fwnode
to device. With ACPI it is possible already, but only to the first
device bind to the node (ACPI device node can be bind to multiple
devices). I don't think there is a function to convert OF node to
device.

We could of course workaround this problem and add fwnode member(s) to
the device_lookup structure. The callers would then have to check is
fwnode or the endpoint (device) name being used, which is not ideal
IMO.


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-13  7:06       ` Andrzej Hajda
@ 2018-06-14 17:25         ` Mats Karrman
  0 siblings, 0 replies; 11+ messages in thread
From: Mats Karrman @ 2018-06-14 17:25 UTC (permalink / raw)
  To: Andrzej Hajda, Heikki Krogerus, Hans de Goede
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

On 2018-06-13 09:06, Andrzej Hajda wrote:

> On 12.06.2018 19:33, Mats Karrman wrote:
>> Hi Andrzej,
>>
>> On 2018-06-07 13:40, Andrzej Hajda wrote:
>>
>>> On 06.06.2018 23:36, Mats Karrman wrote:
>>>> Hello Gentlemen,
>>>>
>>>> I'm trying to get my head around USB role switches in connection with Type-C ports
>>>> and device-trees. So far I have not found much documentation, e.g. there are no
>>>> device-tree bindings documented and really no good examples in existing device
>>>> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
>>>> you a couple of questions instead:
>>>>
>>>> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
>>>> room for three USB busses in the Type-C connector; one high speed and two (?) super-
>>>> speed. These would not all come from the same controller (there might even be
>>>> separate controllers for host and device mode for each bus).
>>>> The case I am working on now only have a single USB2 otg controller so it should
>>>> be possible to make that driver register a role switch but for other cases?
>>>> I imagine it would be possible to create a composite driver as a proxy for all role
>>>> switches but that would probably be different for every platform/product - not
>>>> very elegant. Could the role switch infrastructure be extended to handle arbitrary
>>>> sets of coordinated switches?
>>>>
>>>> 2) How should the connection between the Type-C port and the switches best be
>>>> expressed in a device tree? Using graph I presume, but should it be mixed into the
>>>> existing "usb-connector" or should this be a separate block?
>>>> I think it is unfortunate that the graph use numeric addresses that need to be
>>>> fixed by documentation
>>> I also do not like port numbers, I even have argued for using names
>>> during multiple discussions, but the discussion ended as is :(
>>>
>>>> and already I see problems with the current assignment
>>>> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
>>>> controllers. Graph do support multiple endpoints for one port but then we have
>>>> another level of magic numbers which does not exactly make things easier
>>>> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
>>> Where do you want to use these magic numbers? To describe endpoints? I
>> For some hypothetic worst case scenario where a switch needs to handle
>> different USB controllers for port host and device mode. However I think
>> Heikki and Hans are correct in saying we should wait to worry about that
>> until we have an actual use-case.
>>
>>> guess there should be controllable mux/switch behind the port, it could
>>> be standalone, or a part of bigger IP.
>>> Anyway it should be described by device node, probably parent of USB-C
>> child?
>>
>>> device-node, in such case only links from USB connector going to
>>> different IPs should be described using OF graphs.
>>> And in such case drivers of these devices should
>>> ask/determine/change/communicate their role using in-kernel frameworks
>>> (for example extcon).
>>>
>>> There are many different configurations of USB-C ports
>>> InterfaceControllers, Muxes/Switches, USB related devices, Alternate
>>> Mode devices, PMICs, USB-PDs, ....
>>> Could you describe particular one you have problem with, to make the
>>> discussion more specific.
>> My use-case now is simple. I have a typec port that I need to connect to
>> a dual-role USB controller, probably extended with a usb-role-switch
>> device and I want to express that connection in the device-tree. I was looking
>> for a documented description or example of how to do this but I realize that
>> that is not yet available.
> USB connector bindings [1] are not enough? Did you look at the example?
> I do not know what is exactly your usb-role-switch. Can you provide some

I'm referring to commit fde0aa6c175a4d8aa19e82b86ae0f9278bc8563b
"usb: common: Small class for USB role switches" that is used by the tcpm.
So far I have found no examples of it's usage together with devicetree, only
acpi (and it's not documented in [1], yet).

BR // Mats

> schematics? Or describe which physical lines of USB-C connector are
> connected to which chips (including muxes/switches).
> Two rules of thumb, I think quite simple:
> 1. Do you have USB interface controller? Ie chip which is connected to
> CC lines of USB-C and performs cable detection, maybe PD negotiations,
> etc. This device should be the parent of USB connector node.
> 2. Connections between connector and other chips should be described
> using OF graph.
>
> [1]:
> https://www.kernel.org/doc/Documentation/devicetree/bindings/connector/usb-connector.txt
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-13 13:51         ` Heikki Krogerus
@ 2018-06-15 21:51           ` Mats Karrman
  2018-06-18 12:00             ` Heikki Krogerus
  0 siblings, 1 reply; 11+ messages in thread
From: Mats Karrman @ 2018-06-15 21:51 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Hans de Goede, Andrzej Hajda, Greg Kroah-Hartman, linux-usb, devicetree

On 2018-06-13 15:51, Heikki Krogerus wrote:

> On Tue, Jun 12, 2018 at 07:16:03PM +0200, Mats Karrman wrote:
>> On 2018-06-07 14:01, Heikki Krogerus wrote:
>>
>>> On Thu, Jun 07, 2018 at 09:22:56AM +0200, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 06-06-18 23:36, Mats Karrman wrote:
>>>>> Hello Gentlemen,
>>>>>
>>>>> I'm trying to get my head around USB role switches in connection with Type-C ports
>>>>> and device-trees. So far I have not found much documentation, e.g. there are no
>>>>> device-tree bindings documented and really no good examples in existing device
>>>>> trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
>>>>> you a couple of questions instead:
>>>>>
>>>>> 1) tcpm uses the port device struct to find a single usb_role_switch but there is
>>>>> room for three USB busses in the Type-C connector; one high speed and two (?) super-
>>>>> speed. These would not all come from the same controller (there might even be
>>>>> separate controllers for host and device mode for each bus).
>>> I believe USB 3.2 spec in practice says that the two superspeed
>>> "lanes" must to go to the same controller. Only one will be used for
>>> link training etc. The second one is pulled in after certain state of
>>> enumeration has been passed.
>>>
>>> So we may theoretically have two controllers to deal with, one for
>>> USB2 and another for USB3, but not three.
>>>
>>> But in any case, let's not try to fix theoretical problems that may
>>> never exist.
>>>
>>>> AFAIK the 2nd superspeed USB bus is never used as such. There really is only 1
>>>> USB bus on the Type-C connector, the combined USB-2 + the 1st superspeed bus,
>>>> physically these are 2 separate busses but that is purely for compatibility
>>>> reasons, logically there really only is 1 bus, just like a superspeed Type-A
>>>> connector has both busses physically but logically represents a single bus/port.
>>>>
>>>>> The case I am working on now only have a single USB2 otg controller so it should
>>>>> be possible to make that driver register a role switch but for other cases?
>>>> I guess theoretically a device could use separate role switches / muxes for
>>>> the USB-2 and USB-3 busses, but that would be weird. So lets cross that bridge
>>>> when we reach it.
>>>>
>>>>> I imagine it would be possible to create a composite driver as a proxy for all role
>>>>> switches but that would probably be different for every platform/product - not
>>>>> very elegant. Could the role switch infrastructure be extended to handle arbitrary
>>>>> sets of coordinated switches?
>>>> As said lets cross that bridge when we reach it.
>>> Agreed.
>> OK, I'm buying what you're saying. After reading some manuals for USB3 controllers
>> and USB3 equipped SoC's I realize that most USB3 controllers seem to also support
>> USB2. Makes things easier, although not as flexible as I imagined.
>> One thing that led me astray was the comment for usb_role_switch_register() and the
>> separate device struct pointers for usb2/usb3/udc in the usb_role_switch_desc struct.
>> Still not totally clear to me what they are for?
> They are not really used for anything. Well, not yet at least.
>
> Even if there is only a single physical controller, in case of host,
> there will be separate logical devices representing the USB2 bus the
> USB3 bus. UDC is just UDC, the device is the physical controller.
>
> I added those usb2/usb3/udc handles to the structure because a long
> time a go somebody requested that we should have a way in user space
> to see the USB buses we are dealing with somehow. So the idea was
> never to actually use those in the code. That's why I'm talking about
> symlinks in the TODO comment.

OK, thanks

> But if those are not useful, or confusing, I'm happy to drop them.
>
>>>>> 2) How should the connection between the Type-C port and the switches best be
>>>>> expressed in a device tree? Using graph I presume, but should it be mixed into the
>>>>> existing "usb-connector" or should this be a separate block?
>>> I don't know?
>>>
>>> I'm not super comfortable proposing things for these bindings because
>>> my knowledge of DT is a bit limited. I mostly work with ACPI based
>>> platforms.
>>>
>>> I'm not even completely sure device graph is usable in our case,
>>> though I pretty sure it is.
>>>
>>>>> I think it is unfortunate that the graph use numeric addresses that need to be
>>>>> fixed by documentation and already I see problems with the current assignment
>>>>> (0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
>>>>> controllers. Graph do support multiple endpoints for one port but then we have
>>>>> another level of magic numbers which does not exactly make things easier
>>>>> (e.g. 0=dual or host controller, 1=device controller, 2=mode switch).
>>>> The graph stuff is more Heikki's specialty so I will let Heikki answer this.
>>> I'm not really a graph expert. It is just the only tool in kernel I
>>> can see that allows us to link together all these different components
>>> in HW description, and which has support for both DT and ACPI in Linux
>>> kernel. That is the only reason I've talked about it.
>>>
>>> One of the motivations for the device connection API was that it hides
>>> the actual method these components are linked together in HW
>>> description. What ever the method is, device graph or something else
>>> (we can support different ways), the drivers don't need to know about
>>> it.
>> Ahh, this is complicated and the lack of examples makes it a bit hard to
>> digest. Is it your expectation that the OF graph parsing code will be calling
>> device_connection_add() for every graph connection found in the device
>> tree or maybe for every connection with an "id" property?
> No, the idea is that we parse the graph in
> device_connection_find_match().

I hacked away to see if I could make some sense of this but I didn't get far.
Do you mean that the device_connection_find_match() function should be
extended with code for finding matches in devicetrees as well?

I tried and ended up creating temporary device_connection instances just
to try to satisfy the match function you supply from usb_role_switch_get(),
only the OF graph connection does not have a name to compare with.

>> (Ugh, just realized that the "reg" numeric value of the endpoint node is
>> put in the "id" field of the endpoint struct, bad luck...).
> Isn't the "compatible" property the one that should be used in this
> case? The remote endpoint just has to have compatible property
> matching the con_id, no?

By endpoint you mean the OF node named "endpoint" as described by graph
documentation or something else?
I have not seen or heard of any "endpoint" nodes having "compatible" properties,
only the nodes containing the "port(s)" nodes. The USB controller node
won't have compatible set to "usb-role-switch" so which node do you mean?

> My worry is that currently there is no function to convert a fwnode
> to device. With ACPI it is possible already, but only to the first
> device bind to the node (ACPI device node can be bind to multiple
> devices). I don't think there is a function to convert OF node to
> device.
>
> We could of course workaround this problem and add fwnode member(s) to
> the device_lookup structure. The callers would then have to check is
> fwnode or the endpoint (device) name being used, which is not ideal
> IMO.

"device_connection" structure?

BR // Mats


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB role switches, usb-connector, typec and device trees
  2018-06-15 21:51           ` Mats Karrman
@ 2018-06-18 12:00             ` Heikki Krogerus
  0 siblings, 0 replies; 11+ messages in thread
From: Heikki Krogerus @ 2018-06-18 12:00 UTC (permalink / raw)
  To: Mats Karrman
  Cc: Hans de Goede, Andrzej Hajda, Greg Kroah-Hartman, linux-usb, devicetree

Hi Mats,

On Fri, Jun 15, 2018 at 11:51:17PM +0200, Mats Karrman wrote:
> I hacked away to see if I could make some sense of this but I didn't get far.
> Do you mean that the device_connection_find_match() function should be
> extended with code for finding matches in devicetrees as well?

Yes.

> I tried and ended up creating temporary device_connection instances just
> to try to satisfy the match function you supply from usb_role_switch_get(),

That's how I planned to use it.

> only the OF graph connection does not have a name to compare with.

I think this is about the problem I explained below. So let's just add the
fwnode member to the struct device_connection.

> > > (Ugh, just realized that the "reg" numeric value of the endpoint node is
> > > put in the "id" field of the endpoint struct, bad luck...).
> > Isn't the "compatible" property the one that should be used in this
> > case? The remote endpoint just has to have compatible property
> > matching the con_id, no?
> 
> By endpoint you mean the OF node named "endpoint" as described by graph
> documentation or something else?
> I have not seen or heard of any "endpoint" nodes having "compatible" properties,
> only the nodes containing the "port(s)" nodes. The USB controller node
> won't have compatible set to "usb-role-switch" so which node do you mean?

"compatible" was just a suggestion, but why couldn't for example USB
controller have the "compatible" set also to "usb-role-switch" if it
really acts as the role switch on your system?

        compatible = "<your_platform>-dwc3", "usb-role-switch"

> > My worry is that currently there is no function to convert a fwnode
> > to device. With ACPI it is possible already, but only to the first
> > device bind to the node (ACPI device node can be bind to multiple
> > devices). I don't think there is a function to convert OF node to
> > device.
> > 
> > We could of course workaround this problem and add fwnode member(s) to
> > the device_lookup structure. The callers would then have to check is
> > fwnode or the endpoint (device) name being used, which is not ideal
> > IMO.
> 
> "device_connection" structure?

Yes, sorry about that.

You know, I'm not completely sure what is the benefit in using device
graph with USB connectors? I don't think we need to describe a real
device graph where we could have multiple levels, or do we?

In any case, I guess we are stuck with it since it's used in
Documentation/devicetree/bindings/connector/usb-connector.txt, but I
think in device_connection_find_match() we should still first simply
try to find a named reference (so in case of device tree call
of_parse_phandle(node, con_id, 0)), if that fails try to parse the
graph, and finally if that also fails, check if we have a build-in
description of the connection. Something like this:

void *device_connection_find_match(struct device *dev, const char *con_id,
...
        struct fwnode_handle *fwnode = dev_fwnode(dev);
        struct device_connection connection = { };
        struct fwnode_handle *endpoint = NULL;
        struct fwnode_referece_args args;
        ...
        /* First let's check if there is a named reference. */
        if (!fwnode_property_get_reference_args(fwnode, con_id, NULL, 0, 0,
                                                &args) {
                connection.fwnode = args.fwnode;
                ret = match(&connection, 0, data);
                ...
        }

        /* Let's try device graph */
        while ((endpoint = fwnode_graph_get_next_endpoint(fwnode, endpoint))) {
                struct fwnode_handle *remote;

                remote = fwnode_graph_get_remote_port_parent(endpoint);
                if (!remote)
                        break;

                /* In this example I'm using "compatible" */
                if (!fwnode_property_match_string(remote, "compatible",
                                                  con_id)) {
                        connection.fwnode = remote;
                        ret = match(&connection, 0, data);
                        ...
                }
        }

        /* Finally check if there is a build-in connection description */
        ...


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-06-18 12:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20180606213655epcas1p3e3f704633baa3100e28ff7e02ed85eab@epcas1p3.samsung.com>
2018-06-06 21:36 ` USB role switches, usb-connector, typec and device trees Mats Karrman
2018-06-07  7:22   ` Hans de Goede
2018-06-07 12:01     ` Heikki Krogerus
2018-06-12 17:16       ` Mats Karrman
2018-06-13 13:51         ` Heikki Krogerus
2018-06-15 21:51           ` Mats Karrman
2018-06-18 12:00             ` Heikki Krogerus
2018-06-07 11:40   ` Andrzej Hajda
2018-06-12 17:33     ` Mats Karrman
2018-06-13  7:06       ` Andrzej Hajda
2018-06-14 17:25         ` Mats Karrman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.