* Re: [PATCH 5/5] arm64: tegra: smaug: Add usb-role-switch support
From: Diogo Ivo @ 2026-01-13 14:20 UTC (permalink / raw)
To: Jon Hunter, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <ea60f024-1f39-483c-87e3-36624bd58d49@nvidia.com>
On 1/12/26 22:03, Jon Hunter wrote:
>
> On 04/12/2025 21:27, Diogo Ivo wrote:
>> The USB2 port on Smaug is configured for OTG operation but lacked the
>> required 'usb-role-switch' property, leading to a failed probe and a
>> non-functioning USB port. Add the property along with setting the default
>> role to host.
>>
>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>> ---
>> arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/
>> arm64/boot/dts/nvidia/tegra210-smaug.dts
>> index b8d854f90be7..49bf23d6f593 100644
>> --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
>> +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
>> @@ -1809,6 +1809,8 @@ usb2-0 {
>> status = "okay";
>> vbus-supply = <&usbc_vbus>;
>> mode = "otg";
>> + usb-role-switch;
>> + role-switch-default-mode = "host";
>> };
>
>
> This change does add the following warning when building with CHECK_DTBS
> ...
>
> arch/arm64/boot/dts/nvidia/tegra210-smaug.dtb: padctl@7009f000
> (nvidia,tegra210-xusb-padctl): ports:usb2-0: 'role-switch-default-mode'
> does not match any of the regexes: '^pinctrl-[0-9]+$'
> from schema $id: http://devicetree.org/schemas/phy/nvidia,tegra210-
> xusb-padctl.yaml
>
> I know that there are many warnings seen for the smaug DTB, but it would
> be good to ensure we don't add more.
The 'role-switch-default-mode' property is read by the driver to set the
initial role for the port [0] and is needed in order for the port to work
when booting so in order to fix the warning this property needs to be added
to the binding.
As for the other warning ('connector' is a dependency of 'usb-role-switch')
again I think the binding needs to be adjusted since in the Pixel C the
connector node should be under the (as for now not present)
cros-ec-typec node and the usb2-0 is then modeled as a remote-endpoint
for the full connector. I am currently working on fixing the cros-ec-typec
driver and already have a working fix for automatic role switching but
in any case I think the binding is what needs changing. If you agree
with this then I will add the necessary changes to the DT binding in v2.
Thanks,
Diogo
[0]:
https://elixir.bootlin.com/linux/v6.18.4/source/drivers/phy/tegra/xusb.c#L730
> Cheers
> Jon
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 00/11] Describe PCIe/USB3.0 clock generator on R-Car Gen3
From: Geert Uytterhoeven @ 2026-01-13 14:19 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Krzysztof Kozlowski, Magnus Damm,
Neil Armstrong, Rob Herring, Vinod Koul, Yoshihiro Shimoda,
devicetree, linux-phy, linux-renesas-soc
In-Reply-To: <20260101203938.159161-1-marek.vasut+renesas@mailbox.org>
Hi Marek,
On Thu, 1 Jan 2026 at 21:39, Marek Vasut
<marek.vasut+renesas@mailbox.org> wrote:
> Describe the 9FGV0841 PCIe and USB3.0 clock generator present on various
> R-Car Gen3 boards. The clock generator supplies 100 MHz differential clock
> for PCIe ports, USB 3.0 PHY and SATA.
>
> The series effectively has three parts, the first three patches are part 1,
> which fills in the missing USB 3.0 PHY on R-Car E3 Ebisu and enables it,
> thus aligning the Ebisu USB 3.0 support with the rest of the Gen3 boards.
>
> The second part is description of PCIe root ports on R-Car Gen3 SoCs where
> applicable, in this case that is H3/M3W/M3N/E3. The root port is used with
> PCIe port power control to also control the PCIe port clock. This is needed
> on Gen3 boards, because they often use separate clock output from the PCIe
> clock generator 9FGV0841 to supply clock to the controller and to the PCIe
> port.
>
> The third part is enablement of the 9FGV0841 PCIe clock controller on the
> R-Car Salvator-X/XS, ULCB and Ebisu boards. The boards use the PCIe clock
> controller outputs in a slightly different manner, all use the outputs to
> supply PCIe controllers and slots, as well as USB 3.0 SuperSpeed PHY. The
> ULCB board also uses the 9FGV0841 to supply SATA IP, but this is not yet
> described in DT, therefore it is also not part of this series.
>
> Marek Vasut (11):
> dt-bindings: phy: renesas: usb3-phy: add r8a77990 support
> arm64: dts: renesas: r8a77990: Add USB 3.0 PHY and USB3S0 clock nodes
> arm64: dts: renesas: ebisu: Enable USB 3.0 PHY
> arm64: dts: renesas: r8a77951: Describe PCIe root ports
> arm64: dts: renesas: r8a77960: Describe PCIe root ports
> arm64: dts: renesas: r8a77961: Describe PCIe root ports
> arm64: dts: renesas: r8a77965: Describe PCIe root ports
> arm64: dts: renesas: r8a77990: Describe PCIe root port
> arm64: dts: renesas: salvator-common: Describe PCIe/USB3.0 clock
> generator
> arm64: dts: renesas: ulcb: ulcb-kf: Describe PCIe/USB3.0 clock
> generator
> arm64: dts: renesas: ebisu: Describe PCIe/USB3.0 clock generator
Thanks for your series!
This causes a crash during s2idle on e.g. Salvator-XS with R-Car
H3 ES2.0:
PM: suspend entry (s2idle)
Filesystems sync: 0.014 seconds
Unable to handle kernel NULL pointer dereference at virtual
address 0000000000000008
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
Data abort info:
ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=0000000504be2000
[0000000000000008] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 0000000096000004 [#1] SMP
CPU: 2 UID: 0 PID: 1000 Comm: s2idle Not tainted
6.19.0-rc5-arm64-renesas-04116-g331b300b41b0 #3416 PREEMPT
Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
pstate: a00000c5 (NzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : devres_for_each_res+0x60/0xe8
lr : devres_for_each_res+0x48/0xe8
sp : ffff800083263a70
x29: ffff800083263a70 x28: 0000000000000000 x27: ffff0004c125aec8
x26: ffff800083263af8 x25: ffff80008167bd38 x24: ffff800083263af8
x23: ffff80008071b2f4 x22: ffff0004c125aed0 x21: ffff80008071acd8
x20: ffff80008071ad44 x19: ffff0004c125ac20 x18: 0000000000000001
x17: 00000000ffffffff x16: ffff800081b93ac8 x15: 0056c6b8a4d0b0e4
x14: 00001998170d3e20 x13: 188a4fd930ce7024 x12: 0000000529c8ad17
x11: 00000000000000c0 x10: 0000000000000960 x9 : ffff800083263a50
x8 : ffff800083263b38 x7 : 0000000000000000 x6 : ffff0004c0dc36c0
x5 : ffff800083263af8 x4 : 0000000000000000 x3 : 0000000000000001
x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
Call trace:
devres_for_each_res+0x60/0xe8 (P)
dev_cache_fw_image+0x5c/0x1a8
dpm_for_each_dev+0x50/0x80
fw_pm_notify+0xc0/0xec
blocking_notifier_call_chain_robust+0x70/0xdc
pm_notifier_call_chain_robust+0x24/0x40
pm_suspend+0x13c/0x1e0
state_store+0x7c/0x100
kobj_attr_store+0x14/0x24
sysfs_kf_write+0x78/0x8c
kernfs_fop_write_iter+0x128/0x1d0
vfs_write+0x210/0x390
ksys_write+0x6c/0x100
__arm64_sys_write+0x18/0x20
invoke_syscall+0x44/0x100
el0_svc_common.constprop.0+0x3c/0xd4
do_el0_svc+0x18/0x20
el0_svc+0x24/0xd8
el0t_64_sync_handler+0x98/0xdc
el0t_64_sync+0x154/0x158
Code: f94004dc eb1600df 540000e1 14000018 (f9400780)
---[ end trace 0000000000000000 ]---
note: s2idle[1000] exited with irqs disabled
note: s2idle[1000] exited with preempt_count 1
I do not know what is the actual issue. Adding debug prints to
rs9_suspend() and rs9_resume() shows these functions are not called,
while adding 'status = "disabled"' to the renesas,9fgv0841 clock node
in arch/arm64/boot/dts/renesas/salvator-common.dtsi does fix the issue.
Perhaps you have pending patches for the rs9 or PCIe drivers?
Do you have a clue?
Thanks!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/5] phy: tegra: xusb: Fix ordering issue when switching roles on USB2 ports
From: Diogo Ivo @ 2026-01-13 14:05 UTC (permalink / raw)
To: Jon Hunter, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <86cd3ff0-1609-44cb-911c-f0e97652ca1b@nvidia.com>
On 1/13/26 11:56, Jon Hunter wrote:
>
> On 04/12/2025 21:27, Diogo Ivo wrote:
>> The current implementation of USB2 role switching on Tegra relies on
>> whichever the previous USB controller driver was using the PHY to first
>> "yield" it back to USB_ROLE_NONE before the next controller configures
>> it for the new role. However, no mechanism to guarantee this ordering
>> was implemented, and currently, in the general case, the configuration
>> functions tegra_xhci_id_work() and tegra_xudc_usb_role_sw_work() end up
>> running in the same order regardless of the transition being HOST->DEVICE
>> or DEVICE->HOST, leading to one of these transitions ending up in a
>> non-working state due to the new configuration being clobbered by the
>> previous controller driver setting USB_ROLE_NONE after the fact.
>>
>> Fix this by introducing a helper that waits for the USB2 port’s current
>> role to become USB_ROLE_NONE and add it in the configuration functions
>> above before setting the role to either USB_ROLE_HOST or
>> USB_ROLE_DEVICE. The specific parameters of the helper function are
>> choices that seem reasonable in my testing and have no other basis.
>
> This is no information here about why 6 * 50/60us is deemed to be
> sufficient? May be it is, but a comment would be nice.
>
>> This was tested on a Tegra210 platform (Smaug). However, due to the
>> similar
>> approach in Tegra186 it is likely that not only this problem exists there
>> but that this patch also fixes it.
>>
>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>> ---
>> drivers/phy/tegra/xusb.c | 23 +++++++++++++++++++++++
>> drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++
>> drivers/usb/host/xhci-tegra.c | 15 ++++++++++-----
>> include/linux/phy/tegra/xusb.h | 1 +
>> 4 files changed, 38 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
>> index c89df95aa6ca..e05c3f2d1421 100644
>> --- a/drivers/phy/tegra/xusb.c
>> +++ b/drivers/phy/tegra/xusb.c
>> @@ -740,6 +740,29 @@ static void
>> tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
>> }
>> }
>> +bool tegra_xusb_usb2_port_wait_role_none(struct tegra_xusb_padctl
>> *padctl, int index)
>> +{
>> + struct tegra_xusb_usb2_port *usb2 =
>> tegra_xusb_find_usb2_port(padctl,
>> + index);
>> + int retries = 5;
>> +
>> + if (!usb2) {
>> + dev_err(&usb2->base.dev, "no port found for USB2 lane %u\n",
>> index);
>
> This appears to be a bug. If !usb2 then dereference usb2->base anyway.
It is a bug, will fix in v2.
>> + return false;
>> + }
>> +
>> + do {
>> + if (usb2->role == USB_ROLE_NONE)
>> + return true;
>> +
>> + usleep_range(50, 60);
>> + } while (retries--);
>> +
>> + dev_err(&usb2->base.dev, "timed out waiting for USB_ROLE_NONE");
>> +
>> + return false;
>> +}
>> +
>> static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port
>> *usb2)
>> {
>> struct tegra_xusb_port *port = &usb2->base;
>> diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/
>> udc/tegra-xudc.c
>> index 0c38fc37b6e6..72d725659e5f 100644
>> --- a/drivers/usb/gadget/udc/tegra-xudc.c
>> +++ b/drivers/usb/gadget/udc/tegra-xudc.c
>> @@ -698,8 +698,12 @@ static void tegra_xudc_restore_port_speed(struct
>> tegra_xudc *xudc)
>> static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
>> {
>> + int port = tegra_xusb_padctl_get_port_number(xudc->curr_utmi_phy);
>> int err;
>> + if (!tegra_xusb_usb2_port_wait_role_none(xudc->padctl, port))
>> + return;
>> +
>> pm_runtime_get_sync(xudc->dev);
>> tegra_phy_xusb_utmi_pad_power_on(xudc->curr_utmi_phy);
>> diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-
>> tegra.c
>> index 9c69fccdc6e8..9944593166a3 100644
>> --- a/drivers/usb/host/xhci-tegra.c
>> +++ b/drivers/usb/host/xhci-tegra.c
>> @@ -1352,18 +1352,23 @@ static void tegra_xhci_id_work(struct
>> work_struct *work)
>> struct tegra_xusb_mbox_msg msg;
>> struct phy *phy = tegra_xusb_get_phy(tegra, "usb2",
>> tegra->otg_usb2_port);
>> + enum usb_role role = USB_ROLE_NONE;
>> u32 status;
>> int ret;
>> dev_dbg(tegra->dev, "host mode %s\n", str_on_off(tegra-
>> >host_mode));
>> - mutex_lock(&tegra->lock);
>
> Extra blank line here.
Will fix in v2.
>> - if (tegra->host_mode)
>> - phy_set_mode_ext(phy, PHY_MODE_USB_OTG, USB_ROLE_HOST);
>> - else
>> - phy_set_mode_ext(phy, PHY_MODE_USB_OTG, USB_ROLE_NONE);
>> + if (tegra->host_mode) {
>> + if (!tegra_xusb_usb2_port_wait_role_none(tegra->padctl,
>> + tegra->otg_usb2_port))
>> + return;
>> + role = USB_ROLE_HOST;
>> + }
>> +
>> + mutex_lock(&tegra->lock);
>> + phy_set_mode_ext(phy, PHY_MODE_USB_OTG, role);
>> mutex_unlock(&tegra->lock);
>
> I am trying to understand why you opted to implement it this way around
> and not add the wait loop after setting to the mode to USB_ROLE_NONE in
> the original code all within the context of the mutex?
I did that to minimize the amount of time we wait while holding the
mutex, as we can now possibly wait a significant amount of time for the
role switch. Is this an unneccessary optimization?
Thanks,
Diogo
> Thanks
> Jon
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/5] phy: tegra: xusb: Fix ordering issue when switching roles on USB2 ports
From: Diogo Ivo @ 2026-01-13 13:59 UTC (permalink / raw)
To: Jon Hunter, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <6a0d379f-d215-4efc-bdd0-c9a74d31614a@nvidia.com>
On 1/13/26 11:44, Jon Hunter wrote:
>
> On 13/01/2026 11:35, Jon Hunter wrote:
>>
>> On 04/12/2025 21:27, Diogo Ivo wrote:
>>> The current implementation of USB2 role switching on Tegra relies on
>>> whichever the previous USB controller driver was using the PHY to first
>>> "yield" it back to USB_ROLE_NONE before the next controller configures
>>> it for the new role. However, no mechanism to guarantee this ordering
>>> was implemented, and currently, in the general case, the configuration
>>> functions tegra_xhci_id_work() and tegra_xudc_usb_role_sw_work() end up
>>> running in the same order regardless of the transition being HOST-
>>> >DEVICE
>>> or DEVICE->HOST, leading to one of these transitions ending up in a
>>> non-working state due to the new configuration being clobbered by the
>>> previous controller driver setting USB_ROLE_NONE after the fact.
>>>
>>> Fix this by introducing a helper that waits for the USB2 port’s current
>>> role to become USB_ROLE_NONE and add it in the configuration functions
>>> above before setting the role to either USB_ROLE_HOST or
>>> USB_ROLE_DEVICE. The specific parameters of the helper function are
>>> choices that seem reasonable in my testing and have no other basis.
>>>
>>> This was tested on a Tegra210 platform (Smaug). However, due to the
>>> similar
>>> approach in Tegra186 it is likely that not only this problem exists
>>> there
>>> but that this patch also fixes it.
>>>
>>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>>> ---
>>> drivers/phy/tegra/xusb.c | 23 +++++++++++++++++++++++
>>> drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++
>>> drivers/usb/host/xhci-tegra.c | 15 ++++++++++-----
>>> include/linux/phy/tegra/xusb.h | 1 +
>>> 4 files changed, 38 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
>>> index c89df95aa6ca..e05c3f2d1421 100644
>>> --- a/drivers/phy/tegra/xusb.c
>>> +++ b/drivers/phy/tegra/xusb.c
>>> @@ -740,6 +740,29 @@ static void
>>> tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
>>> }
>>> }
>>> +bool tegra_xusb_usb2_port_wait_role_none(struct tegra_xusb_padctl
>>> *padctl, int index)
>>> +{
>>> + struct tegra_xusb_usb2_port *usb2 =
>>> tegra_xusb_find_usb2_port(padctl,
>>> + index);
>>> + int retries = 5;
>>> +
>>> + if (!usb2) {
>>> + dev_err(&usb2->base.dev, "no port found for USB2 lane %u\n",
>>> index);
>>> + return false;
>>> + }
>>> +
>>> + do {
>>> + if (usb2->role == USB_ROLE_NONE)
>>> + return true;
>>> +
>>> + usleep_range(50, 60);
>>> + } while (retries--);
>>> +
>>> + dev_err(&usb2->base.dev, "timed out waiting for USB_ROLE_NONE");
>>> +
>>> + return false;
>>> +}
>>
>>
>> This patch is causing the following build error today with -next ...
>
> Sorry this is not in -next, I had just applied locally on top!
>
>> MODPOST Module.symvers
>> ERROR: modpost: "tegra_xusb_usb2_port_wait_role_none" [drivers/usb/
>> host/ xhci-tegra.ko] undefined!
>>
>> The above function symbol needs to be exported.
You're right, thanks for catching this. I'll fix it in v2.
>
> Nonetheless this needs to be fixed.
>
> Jon
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/5] phy: tegra: xusb: Fix USB2 port regulator disable logic
From: Diogo Ivo @ 2026-01-13 13:59 UTC (permalink / raw)
To: Jon Hunter, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <c5450fc7-230e-4435-bd1d-3db4f1f6e736@nvidia.com>
On 1/13/26 12:01, Jon Hunter wrote:
>
> On 04/12/2025 21:27, Diogo Ivo wrote:
>> The USB2 PHY mode handling on Tegra210 incorrectly relied on
>> regulator_is_enabled() when determining whether the VBUS supply should
>> be disabled during role changes. This is because regulator_is_enabled()
>> reports exactly what is states and not if there is an unbalanced number
>> of calls between regulator_enable() and regulator_disable(). For
>> example, regulator_is_enabled() always reports true on a fixed-regulator
>> with no enable gpio, which is the case on the Pixel C.
>>
>> This then leads to the PHY driver wrongfully calling regulator_disable()
>> when transitioning from USB_ROLE_DEVICE to USB_ROLE_NONE since the driver
>> did not previously call the corresponding regulator_enable().
>>
>> Fix this by keeping track of the current role and updating the logic to
>> disable the regulator only when the previous role was USB_ROLE_HOST.
>>
>> While at it fix a small typo in a comment.
>>
>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>> ---
>> drivers/phy/tegra/xusb-tegra210.c | 5 +++--
>> drivers/phy/tegra/xusb.h | 1 +
>> 2 files changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/
>> xusb-tegra210.c
>> index 3409924498e9..63ad57d95514 100644
>> --- a/drivers/phy/tegra/xusb-tegra210.c
>> +++ b/drivers/phy/tegra/xusb-tegra210.c
>> @@ -1934,9 +1934,9 @@ static int tegra210_usb2_phy_set_mode(struct phy
>> *phy, enum phy_mode mode,
>> /*
>> * When port is peripheral only or role transitions to
>> * USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
>> - * be enabled.
>> + * enabled.
>> */
>> - if (regulator_is_enabled(port->supply))
>> + if (port->role == USB_ROLE_HOST)
>> regulator_disable(port->supply);
>> tegra210_xusb_padctl_id_override(padctl, false);
>> @@ -1944,6 +1944,7 @@ static int tegra210_usb2_phy_set_mode(struct phy
>> *phy, enum phy_mode mode,
>> }
>> }
>> + port->role = submode;
>> mutex_unlock(&padctl->lock);
>> return err;
>> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
>> index d2b5f9565132..273af147dfd3 100644
>> --- a/drivers/phy/tegra/xusb.h
>> +++ b/drivers/phy/tegra/xusb.h
>> @@ -317,6 +317,7 @@ struct tegra_xusb_usb2_port {
>> enum usb_dr_mode mode;
>> bool internal;
>> int usb3_port_fake;
>> + enum usb_role role;
>> };
>
>
> A similar fix was made to the Tegra186 code by commit cefc1caee9dd
> ("phy: tegra: xusb: Fix unbalanced regulator disable in UTMI PHY mode").
> Although the above looks simpler, I am wondering if we should make a
> similar change to the Tegra210 code so that they both are implemented in
> the same way?
Looking at cefc1caee9dd my approach leads to less changes but I do agree
that standardization benefits us here. However in that case I think we
can take it a step further and actually just have a single function
tegra_xusb_padctl_id_override() (and likewise for vbus_override() and
set_mode()) since they all seem to do the same thing in both platforms.
If not I can simply make this patch look like cefc1caee9dd. Let me know
what you think!
Diogo
> Jon
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/5] phy: tegra: xusb: Fix USB2 port regulator disable logic
From: Diogo Ivo @ 2026-01-13 13:30 UTC (permalink / raw)
To: Vinod Koul, Jonathan Hunter
Cc: Mathias Nyman, Greg Kroah-Hartman, Thierry Reding, JC Kuo,
Kishon Vijay Abraham I, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-usb, linux-tegra, linux-kernel, linux-phy,
devicetree
In-Reply-To: <aUuV2ZYKmM_aYgTv@vaman>
On 12/24/25 07:27, Vinod Koul wrote:
> On 04-12-25, 21:27, Diogo Ivo wrote:
>> The USB2 PHY mode handling on Tegra210 incorrectly relied on
>> regulator_is_enabled() when determining whether the VBUS supply should
>> be disabled during role changes. This is because regulator_is_enabled()
>> reports exactly what is states and not if there is an unbalanced number
>> of calls between regulator_enable() and regulator_disable(). For
>> example, regulator_is_enabled() always reports true on a fixed-regulator
>> with no enable gpio, which is the case on the Pixel C.
>>
>> This then leads to the PHY driver wrongfully calling regulator_disable()
>> when transitioning from USB_ROLE_DEVICE to USB_ROLE_NONE since the driver
>> did not previously call the corresponding regulator_enable().
>>
>> Fix this by keeping track of the current role and updating the logic to
>> disable the regulator only when the previous role was USB_ROLE_HOST.
>>
>> While at it fix a small typo in a comment.
>
> Never mix a patch with something else please. More imp if it is fix
> which will go to rcX. Please send a different patch for typo
Ok, will split for v2.
>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>> ---
>> drivers/phy/tegra/xusb-tegra210.c | 5 +++--
>> drivers/phy/tegra/xusb.h | 1 +
>> 2 files changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
>> index 3409924498e9..63ad57d95514 100644
>> --- a/drivers/phy/tegra/xusb-tegra210.c
>> +++ b/drivers/phy/tegra/xusb-tegra210.c
>> @@ -1934,9 +1934,9 @@ static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
>> /*
>> * When port is peripheral only or role transitions to
>> * USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
>> - * be enabled.
>> + * enabled.
>> */
>> - if (regulator_is_enabled(port->supply))
>> + if (port->role == USB_ROLE_HOST)
>> regulator_disable(port->supply);
>>
>> tegra210_xusb_padctl_id_override(padctl, false);
>> @@ -1944,6 +1944,7 @@ static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
>> }
>> }
>>
>> + port->role = submode;
>> mutex_unlock(&padctl->lock);
>>
>> return err;
>> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
>> index d2b5f9565132..273af147dfd3 100644
>> --- a/drivers/phy/tegra/xusb.h
>> +++ b/drivers/phy/tegra/xusb.h
>> @@ -317,6 +317,7 @@ struct tegra_xusb_usb2_port {
>> enum usb_dr_mode mode;
>> bool internal;
>> int usb3_port_fake;
>> + enum usb_role role;
>> };
>
> Jonathan can we get some t-b for these two patches
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] drm/msm/dp: Correct LeMans/Monaco DP phy Swing/Emphasis setting
From: Yongxing Mou @ 2026-01-13 12:05 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Vinod Koul, Neil Armstrong, linux-arm-msm, linux-phy,
linux-kernel
In-Reply-To: <qnwvucdihyavgn5prchafmfly7mc4b5ts4h2wxjky2cbkv4t33@ct6zncecngvs>
On 1/9/2026 11:27 PM, Dmitry Baryshkov wrote:
> On Fri, Jan 09, 2026 at 04:30:21PM +0800, Yongxing Mou wrote:
>> Currently, the LeMans/Monaco DP PHY operates in DP mode rather than eDP
>> mode. Per the PHY HPG, the Swing and Emphasis settings have been corrected
>
> have been corrected... when?
>
sorry, will correct it next patch.>> to the appropriate DP-mode values.
>>
>> Additionally, the HPG specifies that the LDO value should be set to 0 when
>> in DP mode. These misconfigurations can lead to link training failures on
>> certain dongles.
>
> Separate commit
>
Got it. will update next patch>>
>> Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
>
> Missing Fixes, cc:stable
>
Ack.>> ---
>> drivers/phy/qualcomm/phy-qcom-edp.c | 27 ++++++++++++++++++++++++---
>> 1 file changed, 24 insertions(+), 3 deletions(-)
>>
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] drm/msm/dp: Correct LeMans/Monaco DP phy Swing/Emphasis setting
From: Yongxing Mou @ 2026-01-13 12:04 UTC (permalink / raw)
To: Konrad Dybcio, Vinod Koul, Neil Armstrong
Cc: linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <5187dc04-a1a1-4537-9c80-aaa100dd0033@oss.qualcomm.com>
On 1/9/2026 5:58 PM, Konrad Dybcio wrote:
> On 1/9/26 9:30 AM, Yongxing Mou wrote:
>> Currently, the LeMans/Monaco DP PHY operates in DP mode rather than eDP
>> mode. Per the PHY HPG, the Swing and Emphasis settings have been corrected
>> to the appropriate DP-mode values.
>>
>> Additionally, the HPG specifies that the LDO value should be set to 0 when
>> in DP mode. These misconfigurations can lead to link training failures on
>> certain dongles.
>>
>> Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
>> ---
>> drivers/phy/qualcomm/phy-qcom-edp.c | 27 ++++++++++++++++++++++++---
>> 1 file changed, 24 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
>> index 13feab99feec..5b0d774bd715 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
>> @@ -122,6 +122,13 @@ static const u8 dp_swing_hbr_rbr[4][4] = {
>> { 0x1f, 0xff, 0xff, 0xff }
>> };
>>
>> +static const u8 dp_swing_hbr_rbr_v1[4][4] = {
>> + { 0x07, 0x0f, 0x16, 0x1f },
>> + { 0x11, 0x1e, 0x1f, 0xff },
>> + { 0x16, 0x1f, 0xff, 0xff },
>> + { 0x1f, 0xff, 0xff, 0xff }
>> +};
>
> For these platforms, I see 4 tables of settings:
>
> (Low/High) Swing/Pre-em for (Low/High) HBR
>
> None of them exactly match your change
>
Emm, this table is in LeMans eDP HPG, here are 6 tables. 4 of them use
for eDP mode and reset 2 tables used for DP mode. If my understanding is
incorrect, please correct me. Thanks ~~~ > [...]
>
>> - ldo_config = edp->is_edp ? 0x0 : 0x1;
>> + ldo_config = !edp->is_edp ? 0x0 : 0x1;
>
> You'll notice that this is further wrong, because for eDP, it should be
> 0x81 at low-swing-high-HBR and 0xc1 at low-swing-low-HBR, and 0 at both
> cases of high-swing
>
> Please split the LDO change into a separate commit because it touches
> more platforms
>
> Konrad
>
Yes, you are right, here seems something not correct. i will separate
this change into single one.Here are some parts I don't fully understand
here. Could you please point it? How do we know whether it is in
low‑swing or high‑swing. I didn’t see any logic in the current code that
determines this. Also, the value in Hamoa seems not same with LeMans,it
is 0x51 and 0x91.
While going through the Hamoa HPG, I noticed a potential issue.
static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,...It use
dp_phy_swing_pre_emph_cfg not edp_phy_swing_pre_emph_cfg, but Hamoa
really use edp-panel here.. so does this phy cfg correct here?
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/5] phy: tegra: xusb: Fix USB2 port regulator disable logic
From: Jon Hunter @ 2026-01-13 12:01 UTC (permalink / raw)
To: Diogo Ivo, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <20251204-diogo-tegra_phy-v1-2-51a2016d0be8@tecnico.ulisboa.pt>
On 04/12/2025 21:27, Diogo Ivo wrote:
> The USB2 PHY mode handling on Tegra210 incorrectly relied on
> regulator_is_enabled() when determining whether the VBUS supply should
> be disabled during role changes. This is because regulator_is_enabled()
> reports exactly what is states and not if there is an unbalanced number
> of calls between regulator_enable() and regulator_disable(). For
> example, regulator_is_enabled() always reports true on a fixed-regulator
> with no enable gpio, which is the case on the Pixel C.
>
> This then leads to the PHY driver wrongfully calling regulator_disable()
> when transitioning from USB_ROLE_DEVICE to USB_ROLE_NONE since the driver
> did not previously call the corresponding regulator_enable().
>
> Fix this by keeping track of the current role and updating the logic to
> disable the regulator only when the previous role was USB_ROLE_HOST.
>
> While at it fix a small typo in a comment.
>
> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
> ---
> drivers/phy/tegra/xusb-tegra210.c | 5 +++--
> drivers/phy/tegra/xusb.h | 1 +
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
> index 3409924498e9..63ad57d95514 100644
> --- a/drivers/phy/tegra/xusb-tegra210.c
> +++ b/drivers/phy/tegra/xusb-tegra210.c
> @@ -1934,9 +1934,9 @@ static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
> /*
> * When port is peripheral only or role transitions to
> * USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
> - * be enabled.
> + * enabled.
> */
> - if (regulator_is_enabled(port->supply))
> + if (port->role == USB_ROLE_HOST)
> regulator_disable(port->supply);
>
> tegra210_xusb_padctl_id_override(padctl, false);
> @@ -1944,6 +1944,7 @@ static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
> }
> }
>
> + port->role = submode;
> mutex_unlock(&padctl->lock);
>
> return err;
> diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
> index d2b5f9565132..273af147dfd3 100644
> --- a/drivers/phy/tegra/xusb.h
> +++ b/drivers/phy/tegra/xusb.h
> @@ -317,6 +317,7 @@ struct tegra_xusb_usb2_port {
> enum usb_dr_mode mode;
> bool internal;
> int usb3_port_fake;
> + enum usb_role role;
> };
A similar fix was made to the Tegra186 code by commit cefc1caee9dd
("phy: tegra: xusb: Fix unbalanced regulator disable in UTMI PHY mode").
Although the above looks simpler, I am wondering if we should make a
similar change to the Tegra210 code so that they both are implemented in
the same way?
Jon
--
nvpublic
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/5] phy: tegra: xusb: Fix ordering issue when switching roles on USB2 ports
From: Jon Hunter @ 2026-01-13 11:56 UTC (permalink / raw)
To: Diogo Ivo, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <20251204-diogo-tegra_phy-v1-3-51a2016d0be8@tecnico.ulisboa.pt>
On 04/12/2025 21:27, Diogo Ivo wrote:
> The current implementation of USB2 role switching on Tegra relies on
> whichever the previous USB controller driver was using the PHY to first
> "yield" it back to USB_ROLE_NONE before the next controller configures
> it for the new role. However, no mechanism to guarantee this ordering
> was implemented, and currently, in the general case, the configuration
> functions tegra_xhci_id_work() and tegra_xudc_usb_role_sw_work() end up
> running in the same order regardless of the transition being HOST->DEVICE
> or DEVICE->HOST, leading to one of these transitions ending up in a
> non-working state due to the new configuration being clobbered by the
> previous controller driver setting USB_ROLE_NONE after the fact.
>
> Fix this by introducing a helper that waits for the USB2 port’s current
> role to become USB_ROLE_NONE and add it in the configuration functions
> above before setting the role to either USB_ROLE_HOST or
> USB_ROLE_DEVICE. The specific parameters of the helper function are
> choices that seem reasonable in my testing and have no other basis.
This is no information here about why 6 * 50/60us is deemed to be
sufficient? May be it is, but a comment would be nice.
> This was tested on a Tegra210 platform (Smaug). However, due to the similar
> approach in Tegra186 it is likely that not only this problem exists there
> but that this patch also fixes it.
>
> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
> ---
> drivers/phy/tegra/xusb.c | 23 +++++++++++++++++++++++
> drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++
> drivers/usb/host/xhci-tegra.c | 15 ++++++++++-----
> include/linux/phy/tegra/xusb.h | 1 +
> 4 files changed, 38 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
> index c89df95aa6ca..e05c3f2d1421 100644
> --- a/drivers/phy/tegra/xusb.c
> +++ b/drivers/phy/tegra/xusb.c
> @@ -740,6 +740,29 @@ static void tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
> }
> }
>
> +bool tegra_xusb_usb2_port_wait_role_none(struct tegra_xusb_padctl *padctl, int index)
> +{
> + struct tegra_xusb_usb2_port *usb2 = tegra_xusb_find_usb2_port(padctl,
> + index);
> + int retries = 5;
> +
> + if (!usb2) {
> + dev_err(&usb2->base.dev, "no port found for USB2 lane %u\n", index);
This appears to be a bug. If !usb2 then dereference usb2->base anyway.
> + return false;
> + }
> +
> + do {
> + if (usb2->role == USB_ROLE_NONE)
> + return true;
> +
> + usleep_range(50, 60);
> + } while (retries--);
> +
> + dev_err(&usb2->base.dev, "timed out waiting for USB_ROLE_NONE");
> +
> + return false;
> +}
> +
> static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
> {
> struct tegra_xusb_port *port = &usb2->base;
> diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
> index 0c38fc37b6e6..72d725659e5f 100644
> --- a/drivers/usb/gadget/udc/tegra-xudc.c
> +++ b/drivers/usb/gadget/udc/tegra-xudc.c
> @@ -698,8 +698,12 @@ static void tegra_xudc_restore_port_speed(struct tegra_xudc *xudc)
>
> static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
> {
> + int port = tegra_xusb_padctl_get_port_number(xudc->curr_utmi_phy);
> int err;
>
> + if (!tegra_xusb_usb2_port_wait_role_none(xudc->padctl, port))
> + return;
> +
> pm_runtime_get_sync(xudc->dev);
>
> tegra_phy_xusb_utmi_pad_power_on(xudc->curr_utmi_phy);
> diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
> index 9c69fccdc6e8..9944593166a3 100644
> --- a/drivers/usb/host/xhci-tegra.c
> +++ b/drivers/usb/host/xhci-tegra.c
> @@ -1352,18 +1352,23 @@ static void tegra_xhci_id_work(struct work_struct *work)
> struct tegra_xusb_mbox_msg msg;
> struct phy *phy = tegra_xusb_get_phy(tegra, "usb2",
> tegra->otg_usb2_port);
> + enum usb_role role = USB_ROLE_NONE;
> u32 status;
> int ret;
>
> dev_dbg(tegra->dev, "host mode %s\n", str_on_off(tegra->host_mode));
>
> - mutex_lock(&tegra->lock);
>
Extra blank line here.
> - if (tegra->host_mode)
> - phy_set_mode_ext(phy, PHY_MODE_USB_OTG, USB_ROLE_HOST);
> - else
> - phy_set_mode_ext(phy, PHY_MODE_USB_OTG, USB_ROLE_NONE);
> + if (tegra->host_mode) {
> + if (!tegra_xusb_usb2_port_wait_role_none(tegra->padctl,
> + tegra->otg_usb2_port))
> + return;
>
> + role = USB_ROLE_HOST;
> + }
> +
> + mutex_lock(&tegra->lock);
> + phy_set_mode_ext(phy, PHY_MODE_USB_OTG, role);
> mutex_unlock(&tegra->lock);
I am trying to understand why you opted to implement it this way around
and not add the wait loop after setting to the mode to USB_ROLE_NONE in
the original code all within the context of the mutex?
Thanks
Jon
--
nvpublic
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/5] phy: tegra: xusb: Fix ordering issue when switching roles on USB2 ports
From: Jon Hunter @ 2026-01-13 11:44 UTC (permalink / raw)
To: Diogo Ivo, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <e9f18b0d-6462-43e7-955f-45337914b321@nvidia.com>
On 13/01/2026 11:35, Jon Hunter wrote:
>
> On 04/12/2025 21:27, Diogo Ivo wrote:
>> The current implementation of USB2 role switching on Tegra relies on
>> whichever the previous USB controller driver was using the PHY to first
>> "yield" it back to USB_ROLE_NONE before the next controller configures
>> it for the new role. However, no mechanism to guarantee this ordering
>> was implemented, and currently, in the general case, the configuration
>> functions tegra_xhci_id_work() and tegra_xudc_usb_role_sw_work() end up
>> running in the same order regardless of the transition being HOST->DEVICE
>> or DEVICE->HOST, leading to one of these transitions ending up in a
>> non-working state due to the new configuration being clobbered by the
>> previous controller driver setting USB_ROLE_NONE after the fact.
>>
>> Fix this by introducing a helper that waits for the USB2 port’s current
>> role to become USB_ROLE_NONE and add it in the configuration functions
>> above before setting the role to either USB_ROLE_HOST or
>> USB_ROLE_DEVICE. The specific parameters of the helper function are
>> choices that seem reasonable in my testing and have no other basis.
>>
>> This was tested on a Tegra210 platform (Smaug). However, due to the
>> similar
>> approach in Tegra186 it is likely that not only this problem exists there
>> but that this patch also fixes it.
>>
>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>> ---
>> drivers/phy/tegra/xusb.c | 23 +++++++++++++++++++++++
>> drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++
>> drivers/usb/host/xhci-tegra.c | 15 ++++++++++-----
>> include/linux/phy/tegra/xusb.h | 1 +
>> 4 files changed, 38 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
>> index c89df95aa6ca..e05c3f2d1421 100644
>> --- a/drivers/phy/tegra/xusb.c
>> +++ b/drivers/phy/tegra/xusb.c
>> @@ -740,6 +740,29 @@ static void
>> tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
>> }
>> }
>> +bool tegra_xusb_usb2_port_wait_role_none(struct tegra_xusb_padctl
>> *padctl, int index)
>> +{
>> + struct tegra_xusb_usb2_port *usb2 =
>> tegra_xusb_find_usb2_port(padctl,
>> + index);
>> + int retries = 5;
>> +
>> + if (!usb2) {
>> + dev_err(&usb2->base.dev, "no port found for USB2 lane %u\n",
>> index);
>> + return false;
>> + }
>> +
>> + do {
>> + if (usb2->role == USB_ROLE_NONE)
>> + return true;
>> +
>> + usleep_range(50, 60);
>> + } while (retries--);
>> +
>> + dev_err(&usb2->base.dev, "timed out waiting for USB_ROLE_NONE");
>> +
>> + return false;
>> +}
>
>
> This patch is causing the following build error today with -next ...
Sorry this is not in -next, I had just applied locally on top!
> MODPOST Module.symvers
> ERROR: modpost: "tegra_xusb_usb2_port_wait_role_none" [drivers/usb/host/
> xhci-tegra.ko] undefined!
>
> The above function symbol needs to be exported.
Nonetheless this needs to be fixed.
Jon
--
nvpublic
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/5] phy: tegra: xusb: Fix ordering issue when switching roles on USB2 ports
From: Jon Hunter @ 2026-01-13 11:35 UTC (permalink / raw)
To: Diogo Ivo, Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
JC Kuo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <20251204-diogo-tegra_phy-v1-3-51a2016d0be8@tecnico.ulisboa.pt>
On 04/12/2025 21:27, Diogo Ivo wrote:
> The current implementation of USB2 role switching on Tegra relies on
> whichever the previous USB controller driver was using the PHY to first
> "yield" it back to USB_ROLE_NONE before the next controller configures
> it for the new role. However, no mechanism to guarantee this ordering
> was implemented, and currently, in the general case, the configuration
> functions tegra_xhci_id_work() and tegra_xudc_usb_role_sw_work() end up
> running in the same order regardless of the transition being HOST->DEVICE
> or DEVICE->HOST, leading to one of these transitions ending up in a
> non-working state due to the new configuration being clobbered by the
> previous controller driver setting USB_ROLE_NONE after the fact.
>
> Fix this by introducing a helper that waits for the USB2 port’s current
> role to become USB_ROLE_NONE and add it in the configuration functions
> above before setting the role to either USB_ROLE_HOST or
> USB_ROLE_DEVICE. The specific parameters of the helper function are
> choices that seem reasonable in my testing and have no other basis.
>
> This was tested on a Tegra210 platform (Smaug). However, due to the similar
> approach in Tegra186 it is likely that not only this problem exists there
> but that this patch also fixes it.
>
> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
> ---
> drivers/phy/tegra/xusb.c | 23 +++++++++++++++++++++++
> drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++
> drivers/usb/host/xhci-tegra.c | 15 ++++++++++-----
> include/linux/phy/tegra/xusb.h | 1 +
> 4 files changed, 38 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
> index c89df95aa6ca..e05c3f2d1421 100644
> --- a/drivers/phy/tegra/xusb.c
> +++ b/drivers/phy/tegra/xusb.c
> @@ -740,6 +740,29 @@ static void tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
> }
> }
>
> +bool tegra_xusb_usb2_port_wait_role_none(struct tegra_xusb_padctl *padctl, int index)
> +{
> + struct tegra_xusb_usb2_port *usb2 = tegra_xusb_find_usb2_port(padctl,
> + index);
> + int retries = 5;
> +
> + if (!usb2) {
> + dev_err(&usb2->base.dev, "no port found for USB2 lane %u\n", index);
> + return false;
> + }
> +
> + do {
> + if (usb2->role == USB_ROLE_NONE)
> + return true;
> +
> + usleep_range(50, 60);
> + } while (retries--);
> +
> + dev_err(&usb2->base.dev, "timed out waiting for USB_ROLE_NONE");
> +
> + return false;
> +}
This patch is causing the following build error today with -next ...
MODPOST Module.symvers
ERROR: modpost: "tegra_xusb_usb2_port_wait_role_none"
[drivers/usb/host/xhci-tegra.ko] undefined!
The above function symbol needs to be exported.
Jon
--
nvpublic
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 0/5] Fixes to Tegra USB role switching and Smaug USB role switching enablement
From: Jon Hunter @ 2026-01-13 10:58 UTC (permalink / raw)
To: Rob Herring, Diogo Ivo
Cc: Thierry Reding, linux-tegra, JC Kuo, Krzysztof Kozlowski,
linux-kernel, Mathias Nyman, Conor Dooley, devicetree, linux-usb,
Greg Kroah-Hartman, Vinod Koul, Kishon Vijay Abraham I, linux-phy
In-Reply-To: <176497381829.863612.7431013132555369131.robh@kernel.org>
Hi Diogo,
On 05/12/2025 22:36, Rob Herring wrote:
>
> On Thu, 04 Dec 2025 21:27:16 +0000, Diogo Ivo wrote:
>> Hello,
>>
>> This patch series contains two fixes for USB role switching on the
>> Tegra210 SoC, as well as enabling this feature on the Pixel C.
>>
>> The first patch addresses a wrong check on the logic that disables the
>> VBUS regulator.
>>
>> The second patch guarantees proper ordering of events when switching PHY
>> roles.
>>
>> The third and fourth patches then add the necessary nodes and properties
>> in the Smaug DT in order for role switching to work. Currently with this
>> patch series this feature can only be controlled from userspace by writing
>> the desired role to sysfs as
>>
>> echo "role" > /sys/class/usb_role/usb2-0-role-switch/role
>>
>> with role being one of {device, host, none}.
>>
>> Further patches will enable automatic role switching via the 'cros_ec_typec'
>> driver which is currently broken on Smaug.
>>
>> N.B: This series does not add a 'connector' node under the 'usb-role-switch'
>> property added on patch 04/04 because for Smaug the connector should instead
>> be under the node for 'cros_ec_typec' node and as stated above this
>> driver is currently broken for this device. If it is deemed better to
>> describe it but explicitly disable the node let me know and I will send
>> out a v2.
>>
>> Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>> ---
>> Diogo Ivo (5):
>> usb: host: tegra: Remove redundant pm_runtime_mark_last_busy() call
>> phy: tegra: xusb: Fix USB2 port regulator disable logic
>> phy: tegra: xusb: Fix ordering issue when switching roles on USB2 ports
>> arm64: tegra: smaug: Complete and enable tegra-udc node
>> arm64: tegra: smaug: Add usb-role-switch support
>>
>> arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 13 +++++++++++++
>> drivers/phy/tegra/xusb-tegra210.c | 5 +++--
>> drivers/phy/tegra/xusb.c | 23 +++++++++++++++++++++++
>> drivers/phy/tegra/xusb.h | 1 +
>> drivers/usb/gadget/udc/tegra-xudc.c | 4 ++++
>> drivers/usb/host/xhci-tegra.c | 17 ++++++++++-------
>> include/linux/phy/tegra/xusb.h | 1 +
>> 7 files changed, 55 insertions(+), 9 deletions(-)
>> ---
>> base-commit: a8817ff3b5cd99b0a5af57a92d1a3a7980612550
>> change-id: 20251201-diogo-tegra_phy-86c89cab7377
>>
>> Best regards,
>> --
>> Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
>>
>>
>>
>
>
> My bot found new DTB warnings on the .dts files added or changed in this
> series.
>
> Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
> are fixed by another series. Ultimately, it is up to the platform
> maintainer whether these warnings are acceptable or not. No need to reply
> unless the platform maintainer has comments.
>
> If you already ran DT checks and didn't see these error(s), then
> make sure dt-schema is up to date:
>
> pip3 install dtschema --upgrade
>
>
> This patch series was applied (using b4) to base:
> Base: base-commit a8817ff3b5cd99b0a5af57a92d1a3a7980612550 not known, ignoring
> Base: attempting to guess base-commit...
> Base: tags/v6.18-rc7-8-gf402ecd7a8b6 (exact match)
> Base: tags/v6.18-rc7-8-gf402ecd7a8b6 (use --merge-base to override)
>
> If this is not the correct base, please add 'base-commit' tag
> (or use b4 which does this automatically)
>
> New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/nvidia/' for 20251204-diogo-tegra_phy-v1-0-51a2016d0be8@tecnico.ulisboa.pt:
>
> arch/arm64/boot/dts/nvidia/tegra210-smaug.dtb: padctl@7009f000 (nvidia,tegra210-xusb-padctl): ports:usb2-0: 'role-switch-default-mode' does not match any of the regexes: '^pinctrl-[0-9]+$'
> from schema $id: http://devicetree.org/schemas/phy/nvidia,tegra210-xusb-padctl.yaml
> arch/arm64/boot/dts/nvidia/tegra210-smaug.dtb: padctl@7009f000 (nvidia,tegra210-xusb-padctl): ports:usb2-0: 'connector' is a dependency of 'usb-role-switch'
> from schema $id: http://devicetree.org/schemas/phy/nvidia,tegra210-xusb-padctl.yaml
Per the report above and my other email, this series adds more warnings
and we are trying to avoid that, even if such warnings are seen on other
Tegra platforms.
Jon
--
nvpublic
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: sun4i-usb: replace use of system_wq with system_percpu_wq
From: Marco Crivellari @ 2026-01-13 9:07 UTC (permalink / raw)
To: linux-kernel, linux-phy, linux-arm-kernel, linux-sunxi
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Michal Hocko, Vinod Koul,
Kishon Vijay Abraham I, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland
In-Reply-To: <20251105152023.259813-1-marco.crivellari@suse.com>
On Wed, Nov 5, 2025 at 4:20 PM Marco Crivellari
<marco.crivellari@suse.com> wrote:
> [...]
> drivers/phy/allwinner/phy-sun4i-usb.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
Gentle ping.
Thanks!
--
Marco Crivellari
L3 Support Engineer
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v6 02/11] phy: rockchip: samsung-hdptx: Use usleep_range() instead of udelay()
From: Neil Armstrong @ 2026-01-13 8:13 UTC (permalink / raw)
To: Cristian Ciocaltea, Vinod Koul, Kishon Vijay Abraham I,
Heiko Stuebner, Algea Cao, Dmitry Baryshkov
Cc: kernel, linux-phy, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260113-phy-hdptx-frl-v6-2-8d5f97419c0b@collabora.com>
On 1/13/26 00:20, Cristian Ciocaltea wrote:
> rk_hdptx_dp_reset() is allowed to sleep, hence replace the busy waiting
> with usleep_range(), to allow other threads to run.
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index a65e96694237..89710066d70c 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -1042,7 +1042,7 @@ static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
> reset_control_assert(hdptx->rsts[RST_INIT].rstc);
>
> reset_control_assert(hdptx->rsts[RST_APB].rstc);
> - udelay(10);
> + usleep_range(10, 15);
> reset_control_deassert(hdptx->rsts[RST_APB].rstc);
>
> regmap_update_bits(hdptx->regmap, LANE_REG(0301),
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v6 04/11] phy: rockchip: samsung-hdptx: Consistently use [rk_]hdptx_[tmds_] prefixes
From: Neil Armstrong @ 2026-01-13 8:12 UTC (permalink / raw)
To: Cristian Ciocaltea, Vinod Koul, Kishon Vijay Abraham I,
Heiko Stuebner, Algea Cao, Dmitry Baryshkov
Cc: kernel, linux-phy, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260113-phy-hdptx-frl-v6-4-8d5f97419c0b@collabora.com>
On 1/13/26 00:20, Cristian Ciocaltea wrote:
> Fix the naming inconsistencies for some of the functions and global
> variables:
>
> * Add the missing 'rk_hdptx_' prefix to ropll_tmds_cfg variable
> * Replace '_ropll_tmds_' with '_tmds_ropll_' globally
> * Replace 'hdtpx' with 'hdptx' globally
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 62 +++++++++++------------
> 1 file changed, 31 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 3f8a7f4f5cd8..3c6eb6dbadd0 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -32,17 +32,17 @@
> #define HDPTX_O_PHY_RDY BIT(1)
> #define HDPTX_O_SB_RDY BIT(0)
>
> -#define HDTPX_REG(_n, _min, _max) \
> +#define HDPTX_REG(_n, _min, _max) \
> ( \
> BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) + \
> BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) + \
> ((0x##_n) * 4) \
> )
>
> -#define CMN_REG(n) HDTPX_REG(n, 0000, 00a7)
> -#define SB_REG(n) HDTPX_REG(n, 0100, 0129)
> -#define LNTOP_REG(n) HDTPX_REG(n, 0200, 0229)
> -#define LANE_REG(n) HDTPX_REG(n, 0300, 062d)
> +#define CMN_REG(n) HDPTX_REG(n, 0000, 00a7)
> +#define SB_REG(n) HDPTX_REG(n, 0100, 0129)
> +#define LNTOP_REG(n) HDPTX_REG(n, 0200, 0229)
> +#define LANE_REG(n) HDPTX_REG(n, 0300, 062d)
>
> /* CMN_REG(0008) */
> #define OVRD_LCPLL_EN_MASK BIT(7)
> @@ -397,7 +397,7 @@ struct rk_hdptx_phy {
> unsigned int lanes;
> };
>
> -static const struct ropll_config ropll_tmds_cfg[] = {
> +static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = {
> /* | pms | sdm | sdc | */
> /* rate, mdiv, mdafc, pdiv, rdiv, sdiv, en, deno, nsig, num, n, num, deno, */
> { 594000000ULL, 124, 124, 1, 1, 0, 1, 62, 1, 16, 5, 0, 1, },
> @@ -424,7 +424,7 @@ static const struct ropll_config ropll_tmds_cfg[] = {
> { 25175000ULL, 84, 84, 1, 1, 15, 1, 168, 1, 16, 4, 1, 1, },
> };
>
> -static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
> +static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
> REG_SEQ0(CMN_REG(0009), 0x0c),
> REG_SEQ0(CMN_REG(000a), 0x83),
> REG_SEQ0(CMN_REG(000b), 0x06),
> @@ -514,7 +514,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
> REG_SEQ0(CMN_REG(009b), 0x10),
> };
>
> -static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
> +static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
> REG_SEQ0(CMN_REG(0008), 0x00),
> REG_SEQ0(CMN_REG(0011), 0x01),
> REG_SEQ0(CMN_REG(0017), 0x20),
> @@ -556,14 +556,14 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
> REG_SEQ0(CMN_REG(009b), 0x00),
> };
>
> -static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {
> +static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = {
> REG_SEQ0(SB_REG(0114), 0x00),
> REG_SEQ0(SB_REG(0115), 0x00),
> REG_SEQ0(SB_REG(0116), 0x00),
> REG_SEQ0(SB_REG(0117), 0x00),
> };
>
> -static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
> +static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = {
> REG_SEQ0(LNTOP_REG(0201), 0x00),
> REG_SEQ0(LNTOP_REG(0202), 0x00),
> REG_SEQ0(LNTOP_REG(0203), 0x0f),
> @@ -571,7 +571,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
> REG_SEQ0(LNTOP_REG(0205), 0xff),
> };
>
> -static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
> +static const struct reg_sequence rk_hdptx_tmds_lntop_lowbr_seq[] = {
> REG_SEQ0(LNTOP_REG(0201), 0x07),
> REG_SEQ0(LNTOP_REG(0202), 0xc1),
> REG_SEQ0(LNTOP_REG(0203), 0xf0),
> @@ -579,7 +579,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
> REG_SEQ0(LNTOP_REG(0205), 0x1f),
> };
>
> -static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
> +static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = {
> REG_SEQ0(LANE_REG(0303), 0x0c),
> REG_SEQ0(LANE_REG(0307), 0x20),
> REG_SEQ0(LANE_REG(030a), 0x17),
> @@ -634,7 +634,7 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
> REG_SEQ0(LANE_REG(0620), 0xa0),
> };
>
> -static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
> +static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = {
> REG_SEQ0(LANE_REG(0312), 0x00),
> REG_SEQ0(LANE_REG(0412), 0x00),
> REG_SEQ0(LANE_REG(0512), 0x00),
> @@ -938,7 +938,7 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate,
> return true;
> }
>
> -static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
> +static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
> {
> const struct ropll_config *cfg = NULL;
> struct ropll_config rc = {0};
> @@ -947,9 +947,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
> if (!hdptx->hdmi_cfg.tmds_char_rate)
> return 0;
>
> - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
> - if (hdptx->hdmi_cfg.tmds_char_rate == ropll_tmds_cfg[i].rate) {
> - cfg = &ropll_tmds_cfg[i];
> + for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
> + if (hdptx->hdmi_cfg.tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
> + cfg = &rk_hdptx_tmds_ropll_cfg[i];
> break;
> }
>
> @@ -969,8 +969,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
>
> rk_hdptx_pre_power_up(hdptx);
>
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq);
>
> regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
> regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
> @@ -1012,25 +1012,25 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
> return ret;
> }
>
> -static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx)
> +static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
> {
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
>
> regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
>
> if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) {
> /* For 1/40 bitrate clk */
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq);
> } else {
> /* For 1/10 bitrate clk */
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_lowbr_seq);
> }
>
> regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
> regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
>
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
> - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
> + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq);
>
> return rk_hdptx_post_enable_lane(hdptx);
> }
> @@ -1089,7 +1089,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
> if (mode == PHY_MODE_DP) {
> rk_hdptx_dp_reset(hdptx);
> } else {
> - ret = rk_hdptx_ropll_tmds_cmn_config(hdptx);
> + ret = rk_hdptx_tmds_ropll_cmn_config(hdptx);
> if (ret)
> goto dec_usage;
> }
> @@ -1436,7 +1436,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
> regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
>
> - ret = rk_hdptx_ropll_tmds_mode_config(hdptx);
> + ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
> if (ret)
> rk_hdptx_phy_consumer_put(hdptx, true);
> }
> @@ -1459,11 +1459,11 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
> if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE)
> return -EINVAL;
>
> - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
> - if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate)
> + for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
> + if (hdmi->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
> break;
>
> - if (i == ARRAY_SIZE(ropll_tmds_cfg) &&
> + if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
> !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL))
> return -EINVAL;
>
> @@ -1891,7 +1891,7 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> * while the latter being executed only once, i.e. when clock remains
> * in the prepared state during rate changes.
> */
> - return rk_hdptx_ropll_tmds_cmn_config(hdptx);
> + return rk_hdptx_tmds_ropll_cmn_config(hdptx);
> }
>
> static const struct clk_ops hdptx_phy_clk_ops = {
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v6 03/11] phy: rockchip: samsung-hdptx: Fix coding style alignment
From: Neil Armstrong @ 2026-01-13 8:11 UTC (permalink / raw)
To: Cristian Ciocaltea, Vinod Koul, Kishon Vijay Abraham I,
Heiko Stuebner, Algea Cao, Dmitry Baryshkov
Cc: kernel, linux-phy, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260113-phy-hdptx-frl-v6-3-8d5f97419c0b@collabora.com>
On 1/13/26 00:20, Cristian Ciocaltea wrote:
> Handle a bunch of reported checkpatch.pl complaints:
>
> CHECK: Alignment should match open parenthesis
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 89710066d70c..3f8a7f4f5cd8 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -1624,11 +1624,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
> regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
> LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
> FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
> - ctrl->tx_jeq_even_ctrl));
> + ctrl->tx_jeq_even_ctrl));
> regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
> LN_TX_JEQ_ODD_CTRL_RBR_MASK,
> FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
> - ctrl->tx_jeq_odd_ctrl));
> + ctrl->tx_jeq_odd_ctrl));
> regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
> LN_TX_SER_40BIT_EN_RBR_MASK,
> FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
> @@ -1638,11 +1638,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
> regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
> LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
> FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
> - ctrl->tx_jeq_even_ctrl));
> + ctrl->tx_jeq_even_ctrl));
> regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
> LN_TX_JEQ_ODD_CTRL_HBR_MASK,
> FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
> - ctrl->tx_jeq_odd_ctrl));
> + ctrl->tx_jeq_odd_ctrl));
> regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
> LN_TX_SER_40BIT_EN_HBR_MASK,
> FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
> @@ -1653,11 +1653,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
> regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
> LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
> FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
> - ctrl->tx_jeq_even_ctrl));
> + ctrl->tx_jeq_even_ctrl));
> regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
> LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
> FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
> - ctrl->tx_jeq_odd_ctrl));
> + ctrl->tx_jeq_odd_ctrl));
> regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
> LN_TX_SER_40BIT_EN_HBR2_MASK,
> FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2] phy: qcom: edp: Fix NULL pointer dereference for phy v6 (x1e80100)
From: Neil Armstrong @ 2026-01-13 8:10 UTC (permalink / raw)
To: Val Packett, Vinod Koul, Abel Vesa, Dmitry Baryshkov
Cc: Abel Vesa, linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <20260111083317.604754-1-val@packett.cool>
On 1/11/26 09:25, Val Packett wrote:
> For Glymur SoC support, the com_clk_fwd_cfg callback was added, and a
> stub implementation was added for the v4 of the hardware. However it
> was omitted for the v6, causing a NULL pointer dereference oops on
> Hamoa/Purwa (X1E/X1P) SoC devices. Fix by adding the appropriate stub.
>
> Fixes: add66a6673bc ("phy: qcom: edp: Add Glymur platform support")
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> Signed-off-by: Val Packett <val@packett.cool>
> ---
> v2: pull R-b, reuse v4 function as suggested by Konrad
> v1: https://lore.kernel.org/all/20260109045214.5983-1-val@packett.cool/
>
> drivers/phy/qualcomm/phy-qcom-edp.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index 13feab99feec..7372de05a0b8 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -758,6 +758,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
> .com_power_on = qcom_edp_phy_power_on_v6,
> .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6,
> .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6,
> + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4,
> .com_configure_pll = qcom_edp_com_configure_pll_v6,
> .com_configure_ssc = qcom_edp_com_configure_ssc_v6,
> };
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: qcom: edp: Fix NULL pointer dereference for phy v6 (x1e80100)
From: Neil Armstrong @ 2026-01-13 8:10 UTC (permalink / raw)
To: Konrad Dybcio, Val Packett, Vinod Koul, Abel Vesa,
Dmitry Baryshkov
Cc: linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <bc08f938-a315-4797-931b-5c11d402670b@oss.qualcomm.com>
On 1/9/26 11:49, Konrad Dybcio wrote:
> On 1/9/26 5:50 AM, Val Packett wrote:
>> For Glymur SoC support, the com_clk_fwd_cfg callback was added, and a
>> stub implementation was added for the v4 of the hardware. However it
>> was omitted for the v6, causing a NULL pointer dereference oops on
>> Hamoa/Purwa (X1E/X1P) SoC devices. Fix by adding the appropriate stub.
>>
>> Fixes: add66a6673bc ("phy: qcom: edp: Add Glymur platform support")
>> Signed-off-by: Val Packett <val@packett.cool>
>> ---
>> drivers/phy/qualcomm/phy-qcom-edp.c | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
>> index 13feab99feec..a17492db21d8 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
>> @@ -613,6 +613,11 @@ static int qcom_edp_phy_com_resetsm_cntrl_v6(const struct qcom_edp *edp)
>> val, val & BIT(0), 500, 10000);
>> }
>>
>> +static int qcom_edp_com_clk_fwd_cfg_v6(const struct qcom_edp *edp)
>> +{
>> + return 0;
>> +}
>> +
>> static int qcom_edp_com_bias_en_clkbuflr_v6(const struct qcom_edp *edp)
>> {
>> /* Turn on BIAS current for PHY/PLL */
>> @@ -758,6 +763,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>> .com_power_on = qcom_edp_phy_power_on_v6,
>> .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6,
>> .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6,
>> + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v6,
>
> Let's just point it to the existing qcom_edp_com_clk_fwd_cfg_v4
Yes
Neil
>
> Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2] phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()
From: Neil Armstrong @ 2026-01-13 8:07 UTC (permalink / raw)
To: Wentao Liang, vkoul, kishon, heiko
Cc: linux-phy, linux-rockchip, linux-kernel, linux-arm-kernel, stable
In-Reply-To: <20260109154626.2452034-1-vulab@iscas.ac.cn>
On 1/9/26 16:46, Wentao Liang wrote:
> The for_each_available_child_of_node() calls of_node_put() to
> release child_np in each success loop. After breaking from the
> loop with the child_np has been released, the code will jump to
> the put_child label and will call the of_node_put() again if the
> devm_request_threaded_irq() fails. These cause a double free bug.
>
> Fix by returning directly to avoid the duplicate of_node_put().
>
> Fixes: ed2b5a8e6b98 ("phy: phy-rockchip-inno-usb2: support muxed interrupts")
> Cc: stable@vger.kernel.org
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
>
> ---
> Changes in v2:
> - Drop error jumping label.
> ---
> drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index b0f23690ec30..fe97a26297af 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -1491,7 +1491,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
> rphy);
> if (ret) {
> dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
> - goto put_child;
> + return ret;
> }
> }
>
Good catch !
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 4/6] phy: qcom-qmp-ufs: Add Milos support
From: Neil Armstrong @ 2026-01-13 8:02 UTC (permalink / raw)
To: Luca Weiss, Herbert Xu, David S. Miller, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Alim Akhtar,
Avri Altman, Bart Van Assche, Vinod Koul, Konrad Dybcio
Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-crypto, devicetree, linux-kernel, linux-scsi, linux-phy,
Abel Vesa, Konrad Dybcio, Dmitry Baryshkov
In-Reply-To: <20260112-milos-ufs-v2-4-d3ce4f61f030@fairphone.com>
On 1/12/26 14:53, Luca Weiss wrote:
> Add the init sequence tables and config for the UFS QMP phy found in the
> Milos SoC.
>
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 96 +++++++++++++++++++++++++++++++++
> 1 file changed, 96 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 8a280433a42b..df138a5442eb 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -84,6 +84,68 @@ static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
> [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
> };
>
> +static const struct qmp_phy_init_tbl milos_ufsphy_serdes[] = {
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x14),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x18),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0c),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x98),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x14),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x18),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x32),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0f),
> +};
> +
> +static const struct qmp_phy_init_tbl milos_ufsphy_tx[] = {
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0xcc),
> +};
> +
> +static const struct qmp_phy_init_tbl milos_ufsphy_rx[] = {
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
> + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
> +};
> +
> +static const struct qmp_phy_init_tbl milos_ufsphy_pcs[] = {
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x0b),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> +};
> +
> static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = {
> QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
> QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
> @@ -1165,6 +1227,11 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
> }
>
> /* Regulator bulk data with load values for specific configurations */
> +static const struct regulator_bulk_data milos_ufsphy_vreg_l[] = {
> + { .supply = "vdda-phy", .init_load_uA = 140120 },
> + { .supply = "vdda-pll", .init_load_uA = 18340 },
> +};
> +
> static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = {
> { .supply = "vdda-phy", .init_load_uA = 51400 },
> { .supply = "vdda-pll", .init_load_uA = 14600 },
> @@ -1258,6 +1325,32 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
> .rx2 = 0x1a00,
> };
>
> +static const struct qmp_phy_cfg milos_ufsphy_cfg = {
> + .lanes = 2,
> +
> + .offsets = &qmp_ufs_offsets_v6,
> + .max_supported_gear = UFS_HS_G4,
> +
> + .tbls = {
> + .serdes = milos_ufsphy_serdes,
> + .serdes_num = ARRAY_SIZE(milos_ufsphy_serdes),
> + .tx = milos_ufsphy_tx,
> + .tx_num = ARRAY_SIZE(milos_ufsphy_tx),
> + .rx = milos_ufsphy_rx,
> + .rx_num = ARRAY_SIZE(milos_ufsphy_rx),
> + .pcs = milos_ufsphy_pcs,
> + .pcs_num = ARRAY_SIZE(milos_ufsphy_pcs),
> + },
> + .tbls_hs_b = {
> + .serdes = sm8550_ufsphy_hs_b_serdes,
> + .serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> + },
> +
> + .vreg_list = milos_ufsphy_vreg_l,
> + .num_vregs = ARRAY_SIZE(milos_ufsphy_vreg_l),
> + .regs = ufsphy_v6_regs_layout,
> +};
> +
> static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
> .lanes = 1,
>
> @@ -2166,6 +2259,9 @@ static int qmp_ufs_probe(struct platform_device *pdev)
>
> static const struct of_device_id qmp_ufs_of_match_table[] = {
> {
> + .compatible = "qcom,milos-qmp-ufs-phy",
> + .data = &milos_ufsphy_cfg,
> + }, {
> .compatible = "qcom,msm8996-qmp-ufs-phy",
> .data = &msm8996_ufsphy_cfg,
> }, {
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 11/24] scsi: ufs: mediatek: Rework probe function
From: Peter Wang (王信友) @ 2026-01-13 7:26 UTC (permalink / raw)
To: chu.stanley@gmail.com, robh@kernel.org,
Chunfeng Yun (云春峰), kishon@kernel.org,
James.Bottomley@HansenPartnership.com, bvanassche@acm.org,
AngeloGioacchino Del Regno,
Chaotian Jing (井朝天), conor+dt@kernel.org,
lgirdwood@gmail.com, nicolas.frattaroli@collabora.com,
vkoul@kernel.org, krzk+dt@kernel.org, p.zabel@pengutronix.de,
alim.akhtar@samsung.com, krzk@kernel.org,
neil.armstrong@linaro.org, matthias.bgg@gmail.com,
avri.altman@wdc.com, broonie@kernel.org,
martin.petersen@oracle.com
Cc: linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org,
Louis-Alexis Eyraud, kernel@collabora.com
In-Reply-To: <26c68bb1-1e63-4b47-babc-21ae27e3205e@collabora.com>
On Mon, 2026-01-12 at 16:02 +0100, AngeloGioacchino Del Regno wrote:
> No, MediaTek's reset hardware implementation is not the same as Texas
> Instruments.
> It was *very similar* to TI in the past (years ago, around the MT6795
> Helio
> generation times).
>
> MediaTek's reset controller - by hardware - is definitely different
> from the one
> found in TI SoCs.
>
> Regards,
> Angelo
I did not notice this change.
Will you be helping to upstream MediaTek's reset controller instead of
TI's?
Thanks
Peter
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2] phy: qcom: edp: Fix NULL pointer dereference for phy v6 (x1e80100)
From: Yijie Yang @ 2026-01-13 7:23 UTC (permalink / raw)
To: Val Packett, Vinod Koul, Neil Armstrong, Abel Vesa,
Dmitry Baryshkov
Cc: Abel Vesa, linux-arm-msm, linux-phy, linux-kernel, yijie.yang
In-Reply-To: <20260111083317.604754-1-val@packett.cool>
On 1/11/2026 4:25 PM, Val Packett wrote:
> For Glymur SoC support, the com_clk_fwd_cfg callback was added, and a
> stub implementation was added for the v4 of the hardware. However it
> was omitted for the v6, causing a NULL pointer dereference oops on
> Hamoa/Purwa (X1E/X1P) SoC devices. Fix by adding the appropriate stub.
>
> Fixes: add66a6673bc ("phy: qcom: edp: Add Glymur platform support")
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> Signed-off-by: Val Packett <val@packett.cool>
> ---
> v2: pull R-b, reuse v4 function as suggested by Konrad
> v1: https://lore.kernel.org/all/20260109045214.5983-1-val@packett.cool/
>
> drivers/phy/qualcomm/phy-qcom-edp.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index 13feab99feec..7372de05a0b8 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -758,6 +758,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
> .com_power_on = qcom_edp_phy_power_on_v6,
> .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6,
> .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6,
> + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4,
> .com_configure_pll = qcom_edp_com_configure_pll_v6,
> .com_configure_ssc = qcom_edp_com_configure_ssc_v6,
> };
Tested-by: Yijie Yang <yijie.yang@oss.qualcomm.com> # Purwa-IoT-EVK
--
Best Regards,
Yijie
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 0/4] Add eMMC PHY support for Axiado AX3000 SoC
From: Tzu-Hao Wei @ 2026-01-13 6:16 UTC (permalink / raw)
To: Krzysztof Kozlowski, SriNavmani A, Prasad Bolisetty, Vinod Koul,
Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, openbmc
In-Reply-To: <85c3fe42-22a1-4b8d-85a6-f7541d8c942e@kernel.org>
On 1/12/2026 4:32 PM, Krzysztof Kozlowski wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> On 09/01/2026 10:43, Tzu-Hao Wei wrote:
>> Axiado AX3000 SoC contains Arasan PHY which provides the interface to the
>> HS200 eMMC controller.
>>
>> This series includes:
>> 1. Add bindings for Axiado AX3000 eMMC PHY
>> 2. Add Axiado AX3000 eMMC phy driver
>> 3. Update MAINTAINERS for the new driver
>> 4. Update Axiado AX3000 device tree
>>
>> Changes: (The previous version was mixed with Host driver, so I separate
>> the PHY driver as a new thread)
>> - Fix property order in required section to match properties section
>> - Fixed example to use lowercase hex and proper node naming
>> - Removed wrapper functions, use readl/writel directly
>> - Replaced manual polling loops with read_poll_timeout macro
>> - Used devm_platform_ioremap_resource instead of separate calls
>> - Removed unnecessary of_match_node check
>> - Used dev_err_probe for error reporting
>> - Added proper Kconfig dependencies (ARCH_AXIADO || COMPILE_TEST)
>> - Fixed various coding style issues
>> - Link to previous patches: https://lore.kernel.org/all/20251222-axiado-ax3000-add-emmc-host-driver-support-v1-0-5457d0ebcdb4@axiado.com/
>>
>
> So v2. Always version your patches correctly.
>
> Best regards,
> Krzysztof
Hi Krzysztof,
Understood, thanks for clarifying.
Although the PHY patches were split into a separate thread from the
previous combined host+phy series, they are a continuation of the same
work and therefore should follow the existing versioning.
Just to confirm before resending: I will submit the next eMMC PHY series
as v2. Please let me know if this is not correct.
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/4] MAINTAINERS: Add Axiado AX3000 eMMC PHY driver
From: Tzu-Hao Wei @ 2026-01-13 3:38 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-phy,
devicetree, linux-arm-kernel, linux-kernel, openbmc
In-Reply-To: <20260111-watchful-pigeon-of-brotherhood-6ada05@quoll>
On 1/11/2026 6:40 PM, Krzysztof Kozlowski wrote:
>>
>> +AXIADO EMMC PHY DRIVER
>> +M: SriNavmani A <srinavmani@axiado.com>
>
> No activity:
> https://lore.kernel.org/all/?q=f%3Asrinavmani%40axiado.com
>
>> +M: Tzu-Hao Wei <twei@axiado.com>
>> +M: Prasad Bolisetty <pbolisetty@axiado.com>
>
> No reviews:
> https://lore.kernel.org/all/?q=f%3Apbolisetty%40axiado.com
>
> Are these maintainers going to actually maintain code? At least Prasad
> should provide proper review now.
>
I'll ask them to Ack/Review the patches.
>> +L: linux-phy@lists.infradead.org (moderated for non-subscribers)
>> +S: Maintained
>> +F: Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml
>
>> +F: drivers/phy/axiado/Kconfig
>> +F: drivers/phy/axiado/phy-axiado-emmc.c
>
> If you are a maintainer of Kconfig you imply you maintain everything, so
> simply entire directory...
>
Yes, we will maintain everything in drivers/phy/axiado/
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox