[PATCH 3/5] phy: qualcomm: qmp-combo: Add preliminary USB4 support
Konrad Dybcio
konrad.dybcio at oss.qualcomm.com
Tue Jun 16 04:44:48 PDT 2026
On 5/28/26 10:00 AM, Dmitry Baryshkov wrote:
> On Fri, May 22, 2026 at 02:05:14PM +0200, Konrad Dybcio wrote:
>> On 5/20/26 5:06 PM, Dmitry Baryshkov wrote:
>>> On Tue, May 19, 2026 at 10:12:06AM +0200, Konrad Dybcio wrote:
>>>> On 5/18/26 5:38 PM, Dmitry Baryshkov wrote:
>>>>> On Mon, May 18, 2026 at 04:15:16PM +0200, Konrad Dybcio wrote:
>>>>>> On 5/18/26 3:57 PM, Dmitry Baryshkov wrote:
>>>>>>> On Mon, May 18, 2026 at 12:29:50PM +0200, Konrad Dybcio wrote:
>>>>>>>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>>>>>>
>>>>>>>> Some Combo PHYs (so far only on SC8280XP, X1E80100 and Glymur), come in
>>>>>>>> a flavor called USB43DP, which as the name implies, features USB4, USB3
>>>>>>>> and DP signal processing capabilities. In that architecture, USB3 and
>>>>>>>> USB4 PHYs share the same USB_PLL while featuring separate logic spaces.
>>>>>>>> The DP part is roughly the same as on the instances without USB4.
>>>>>>>>
>>>>>>>> The USB4 and USB3/DP operation modes of the PHY are mutually exclusive.
>>>>>>>> Only one USB protocol (and flavor of pipe clock) can be active at a
>>>>>>>> given moment (not to be confused with USB3 not being able to be
>>>>>>>> tunneled as USB4 packets - that of course remains possible).
>>>>>>>> The DP PLL is still used for clocking tunneled DP links. It may be
>>>>>>>> turned off to save power when no tunnels are active, but that's left as
>>>>>>>> a TODO item for now.
>>>>>>>>
>>>>>>>> Due to the nature of USB4, the Type-C handling happens entirely inside
>>>>>>>> the Host Router, and as such the QMPPHY's mux_set() function is
>>>>>>>> nullified for the period when USB4 PHY remains active. This is strictly
>>>>>>>> necessary, as the Host Router driver is going to excercise manual
>>>>>>>> control over the USB4 PHY's power state, which is needed by the suspend
>>>>>>>> and resume flows. Failure to control that synchronously with other
>>>>>>>> parts of the code results in a SoC crash by unlocked access.
>>>>>>>>
>>>>>>>> Because of that, a new struct phy is spawned to expose the USB4 mode,
>>>>>>>> along with a .set_mode callback to allow toggling between USB4 and TBT3
>>>>>>>> submodes.
>>>>>>>>
>>>>>>>> Thunderbolt 3, having a number of differences vs USB4, requires a
>>>>>>>> couple specific overrides, pertaining to electrical characteristics,
>>>>>>>> which are easily accommodated for.
>>>>>>>>
>>>>>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>>>>>> ---
>>>>>>>> drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 392 ++++++++++++++++++++++++------
>>>>>>>> 1 file changed, 322 insertions(+), 70 deletions(-)
>>>>>>>>
>>>>>>>
>>>>>>> Overall it looks good. The major question (after looking at TODOs), do
>>>>>>> we need a separate submode for USB+DP / TBT+DP?
>>>>>>
>>>>>> The problem space is as follows:
>>>>>>
>>>>>> After a TBT (collectively TBT3+ and USB4) link has been established and
>>>>>> we have a link partner, we may (based on the HW capabilities and user
>>>>>> config, such as kernel params but not only) start or stop a DP tunnel at
>>>>>> runtime. On Qualcomm hardware, the PHY is kept in USB4 mode and its DP
>>>>>> AUX lines are not used (instead, the encapsulated DP AUX packets are r/w
>>>>>> entirely within the USB4 subsystem via a pair of FIFOs that Linux sees
>>>>>> as a separate DP AUX host)
>>>>>
>>>>> So far so good. But I still don't grok if having a DP-over-USB4 is a
>>>>> separate submode or not. I.e. I see code (and TODOs) to detect and
>>>>> handle DP going on and off. Would it be better if we specify that
>>>>> explicitly?
>>>>
>>>> I really don't want to end up in a situation like we have with:
>>>>
>>>> $ rg _USB include/linux/phy/phy.h
>>>> 29: PHY_MODE_USB_HOST,
>>>> 30: PHY_MODE_USB_HOST_LS,
>>>> 31: PHY_MODE_USB_HOST_FS,
>>>> 32: PHY_MODE_USB_HOST_HS,
>>>> 33: PHY_MODE_USB_HOST_SS,
>>>> 34: PHY_MODE_USB_DEVICE,
>>>> 35: PHY_MODE_USB_DEVICE_LS,
>>>> 36: PHY_MODE_USB_DEVICE_FS,
>>>> 37: PHY_MODE_USB_DEVICE_HS,
>>>> 38: PHY_MODE_USB_DEVICE_SS,
>>>> 39: PHY_MODE_USB_OTG,
>>>>
>>>>>> Then, on hamoa/glymur specifically, any of the 3 USB4-capable DP hosts
>>>>>> can be muxed to either of the 2 DPIN ports on any of the 3 USB4 routers
>>>>>> (and each of these routers is hardwired to one of the PHYs).
>>>>>>
>>>>>> To underline, we have 3 DP producers and 6 consumers. If there's e.g. a
>>>>>> super high-res display at one of the physical ports, or a long
>>>>>> daisy-chain, we may need to use 2 DPTXes to service 1 receptacle. Then,
>>>>>> we would only need one of the PHYs (associated with the router that's
>>>>>> wired to that port) to provide a DP clock.
>>>>>>
>>>>>> This, along with the normal (logical or physical) present/absent status
>>>>>> can change at runtime. My plan is to use phy_set_opts(dp_tunelling=true)
>>>>>> or something along those lines to toggle that bit as necessary
>>>>>
>>>>> I don't see phy_set_opts(). So maybe a submode then...
>>>>
>>>> Sorry, I misremembered the name. The function is phy_configure(), and it
>>>> takes a union phy_configure_opts, hence the confusion
>>>
>>> So, phy_configure() will be called for the DP PHY to set the DP opts,
>>> but how do you plan to determine if DP is on or not? Or do you plan to
>>> add phy_tbt_configure_opts ?
>>>
>>> Another obvious option would be to set the flag if DP PHY is being tuned
>>> on / off. I don't know if that fulfills your needs.
>>
>> Either this or tbt_configure_opts. We still have the muxing question to
>> chew through.
>>
>> The bottom line is that all AUX traffic happens between the "AUX adapters"
>> within USB4SS, talking over thunderbolt to other AUX adapters on the LTTPRs
>> and the far-end device (and anything inbetween in a chained topology) meaning
>> we only need to engage the DP host itself (and therefore the PHY) after we've
>> already performed the capability negotiations
>
> I hope you mean USB link capabilities. DP host still needs to ping LTTPRs
> and read all the DP properties on its own. I don't think we want to leak
> that to the other layers.
I must crush your hopes.
There's some preliminary TBT-layer setup (handled by the tbt driver in
Linux), followed by the expected DPCD (and alike) r/w accesses, which on
our hw must happen through the DP adapters housed inside USB4SS (again,
because the DPTX's auxbus is NOPed out). Think of it as just another
i2c_aux provider.
Konrad
More information about the linux-phy
mailing list