* Re: [REGRESSION] HDMI monitor not working on Radxa Rock 5B after phy rockchip samsung hdptx HDMI 2.1 FRL patchset
From: Cristian Ciocaltea @ 2026-02-18 0:52 UTC (permalink / raw)
To: dubito, Vinod Koul, Neil Armstrong, Heiko Stuebner, linux-phy,
linux-arm-kernel, linux-rockchip, linux-kernel, regressions
In-Reply-To: <4544ec4ccfa49cbdffee098878df7806223935a0.camel@online.de>
Hi Thomas,
On 2/16/26 12:48 PM, Thomas Niederprüm wrote:
> Hi Cristian,
>
> Am Montag, dem 16.02.2026 um 03:18 +0200 schrieb Cristian Ciocaltea:
>> Hi Thomas,
>>
>> On 2/14/26 12:00 AM, Thomas Niederprüm wrote:
>>> Hi Cristian,
>>>
>>>
>>> Am Freitag, dem 13.02.2026 um 00:04 +0200 schrieb Cristian Ciocaltea:
>>>> Hi Thomas,
>>>>
>>>> On 2/11/26 11:20 PM, Thomas Niederprüm wrote:
>>>>> Hi,
>>>>>
>>>>> I'm running a Radxa Rock 5B (rk3588) on a 10+ year old Samsung TV screen
>>>>> connected via HDMI. This worked flawlessly in 6.18.7 but does not work
>>>>> on
>>>>> linux-
>>>>> next. I bisected the problem and identified commit 3481fc04 to be the
>>>>> first
>>>>> bad
>>>>> commit. This points to the phy PLL clock rate calculation to be the
>>>>> problem
>>>>> in
>>>>> connection with my monitor. As it seems relevant, I attached the EDID of
>>>>> my
>>>>> monitor.
>>>>>
>>>>> I'm booting the kernel out of EDK2 after which efifb is correctly taking
>>>>> over
>>>>> the initialized display and I can see the initial kernel boot messages
>>>>> on
>>>>> the
>>>>> HDMI output. After the drm/kms in the kernel takes over the screen
>>>>> shortly
>>>>> turns
>>>>> black, changes resolution, and then correctly displays on 6.18.7.
>>>>> However,
>>>>> in
>>>>> linux-next the screen remains black after kms took over. I cannot see
>>>>> any
>>>>> obvious differences in the boot logs but I attached two boot logs, one
>>>>> for
>>>>> the
>>>>> working 6.18.7 kernel and one for the non-working linux-next kernel.
>>>>>
>>>>> When reverting 3481fc04..de5dba83 (i.e. the faulty commit and the ones
>>>>> that
>>>>> followed in the HDMI 2.1 FRL series) I can build a working kernel from
>>>>> linux-
>>>>> next.
>>>>>
>>>>> I don't know where to dig from here but I'm happy to run any test
>>>>> necessary
>>>>> to
>>>>> track down the problem.
>>>>
>>>> It'd be helpful if you could resend the logs after booting both kernels
>>>> with
>>>> the
>>>> following params (requires CONFIG_DYNAMIC_DEBUG=y):
>>>>
>>>> rockchipdrm.dyndbg=+p dw_hdmi_qp.dyndbg=+p
>>>> phy_rockchip_samsung_hdptx.dyndbg=+p
>>>>
>>>> As well as running the command below before connecting your display/TV:
>>>>
>>>> $ echo 0x4 > /sys/module/drm/parameters/debug
>>>>
>>>> I've noticed you're forcing "video=HDMI-A-1:1920x1080M@60", which should
>>>> be
>>>> anyway the preferred mode (according to the EDID).
>>>
>>> I dumped the kernel messages for a freshly built v6.19 and a linux-next
>>> image.
>>> For each kernel I booted with the suggested debug options and forcing the
>>> modes
>>> 1920x1080@60, 1920x1080@50, 1920x1080@30. The boot logs are attached. For
>>> v6.19
>>> all modes work. Running linux-next, 1920x1080@60 and 1920x1080@50 don't work
>>> but
>>> 1920x1080@30 works.
>>>
>>>> Did you try choosing a different one, e.g. 1920x1080@50 or 1920x1080@30
>>>> (they
>>>> are supported according to the listing in CTA-861 Extension Block). That's
>>>> more
>>>> a test to confirm the issue affects a particular modeline, or is more
>>>> general.
>>>>
>>>
>>> As stated above, if I force 1920x1080@30 the screen turns on in linux-next.
>>> 1920x1080@60 and 1920x1080@50 don't work. This points to something specific
>>> to
>>> the modeline.
>>>
>>> By diff'ing the relevant part of the logs between kernels one can see that
>>> in
>>> the cases where the screen stays black the log lacks the following lines:
>>>
>>> rockchip-hdptx-phy fed60000.phy: rk_hdptx_ropll_tmds_cmn_config
>>> rate=185625000 mdiv=155 sdiv=4 sdm_en=1 k_sign=1 k=16 lc=62
>>> rockchip-hdptx-phy fed60000.phy: PHY clk ready
>>>
>>> So obviously the PHY clock never gets ready.
>>>
>>> I also attached the diffs I made.
>>
>> Thanks for checking this out! The behavior is really unexpected and I'm still
>> unable to reproduce on my end, i.e. even tested with a Samsung TV, which is
>> almost as old as yours:
>>
>> # Mine
>> Vendor & Product Identification:
>> Manufacturer: SAM
>> Model: 2685
>> Serial Number: 1 (0x00000001)
>> Made in: week 46 of 2012
>>
>> # Yours
>> Vendor & Product Identification:
>> Manufacturer: SAM
>> Model: 1641
>> Serial Number: 1 (0x00000001)
>> Made in: week 47 of 2009
>>
>> I added some more debug information, hence could you please apply commit [1]
>> on
>> your next-20260213 kernel and share the logs after testing again the
>> 1920x1080@50 and 1920x1080@30 modes?
>>
>> [1]
>> https://gitlab.collabora.com/cristicc/linux-next/-/commit/2ce4b1fb60fc601068abbe9131c05c4f09f1380c
>>
>>
>
> Please find the logs attached.
Sorry, I somehow missed the following warning message, though it has been
already present in all the logs you've sent to me so far:
rockchip-hdptx-phy fed60000.phy: PLL locked by unknown consumer!
That indicates the PHY has been preconfigured by an external component (e.g. the
bootloader), which is actually a scenario that I didn't verify.
However, this just another way to expose a limitation of the current approach
for managing the TMDS character rate: done via the Common Clock Framework API
instead of the HDMI PHY configuration API.
As a matter of fact, it was actually an item on my TODOs list for quite a while,
but blocked until recently due to several dependencies waiting to be merged
upstream.
Hence I took the opportunity to finalize this task - please give the following
commits in my rk3588-hdmi-debug branch [2] a try:
07b579f28fe0 ("phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc")
ef714855512a ("phy: rockchip: samsung-hdptx: Exclusively use PHY config API for PLL changes")
In case further debugging is necessary, you may also pick:
1cddea39cd92 ("[DEBUG] drm/rockchip: Add HDMI verbose logging")
In the meantime, I'll do some more testing on my end. Moreover, I'm going to
prepare a couple of additional cleanup patches (unrelated to this issue) before
sending the series out.
Regards,
Cristian
[2] https://gitlab.collabora.com/cristicc/linux-next/-/commits/rk3588-hdmi-debug
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [REGRESSION] HDMI monitor not working on Radxa Rock 5B after phy rockchip samsung hdptx HDMI 2.1 FRL patchset
From: Cristian Ciocaltea @ 2026-02-18 1:22 UTC (permalink / raw)
To: dubito, Vinod Koul, Neil Armstrong, Heiko Stuebner, linux-phy,
linux-arm-kernel, linux-rockchip, linux-kernel, regressions
In-Reply-To: <08369c90-fbab-477d-9ac6-388deddfd3b1@collabora.com>
On 2/18/26 2:52 AM, Cristian Ciocaltea wrote:
> Hi Thomas,
[...]
>
> Sorry, I somehow missed the following warning message, though it has been
> already present in all the logs you've sent to me so far:
>
> rockchip-hdptx-phy fed60000.phy: PLL locked by unknown consumer!
>
> That indicates the PHY has been preconfigured by an external component (e.g. the
> bootloader), which is actually a scenario that I didn't verify.
>
> However, this just another way to expose a limitation of the current approach
> for managing the TMDS character rate: done via the Common Clock Framework API
> instead of the HDMI PHY configuration API.
>
> As a matter of fact, it was actually an item on my TODOs list for quite a while,
> but blocked until recently due to several dependencies waiting to be merged
> upstream.
>
> Hence I took the opportunity to finalize this task - please give the following
> commits in my rk3588-hdmi-debug branch [2] a try:
I've just realized I introduced a regression while doing some cleanup work, hence
please ignore this until further notice.
Cristian
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 2/6] scsi: ufs: qcom,sc7180-ufshc: dt-bindings: Document the Milos UFS Controller
From: Martin K. Petersen @ 2026-02-18 2:33 UTC (permalink / raw)
To: Luca Weiss
Cc: Martin K. Petersen, Herbert Xu, David S. Miller, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Alim Akhtar,
Avri Altman, Bart Van Assche, Vinod Koul, Neil Armstrong,
Konrad Dybcio, ~postmarketos/upstreaming, phone-devel,
linux-arm-msm, linux-crypto, devicetree, linux-kernel, linux-scsi,
linux-phy, Krzysztof Kozlowski
In-Reply-To: <DGDW69W84LJ1.2GHM2WU31VANR@fairphone.com>
Luca,
> I've added you to this email now since you seem to pick up most
> patches for these files. Could you take this one please to unblock
> Milos UFS dts?
Sure. Once the merge window is closed...
--
Martin K. Petersen
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: qcom: m31-eusb2: clear PLL_EN during init
From: Konrad Dybcio @ 2026-02-18 10:58 UTC (permalink / raw)
To: Elson Serrao, Vinod Koul, Konrad Dybcio, Neil Armstrong,
Wesley Cheng, Johan Hovold, Dmitry Baryshkov
Cc: linux-arm-msm, linux-phy, linux-kernel, stable
In-Reply-To: <20260217201130.2804550-1-elson.serrao@oss.qualcomm.com>
On 2/17/26 9:11 PM, Elson Serrao wrote:
> The driver currently sets bit 0 of USB_PHY_CFG1 (PLL_EN) during PHY
> initialization. According to the M31 EUSB2 PHY hardware documentation,
> this bit is intended only for test/debug scenarios and does not control
> mission mode operation. Keeping PLL_EN asserted causes the PHY to draw
> additional current during USB bus suspend. Clearing this bit results in
> lower suspend power consumption without affecting normal operation.
>
> Update the driver to leave PLL_EN cleared as recommended by the hardware
> documentation.
>
> Fixes: 9c8504861cc4 ("phy: qcom: Add M31 based eUSB2 PHY driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH net-next] doc: generic phy: update generic PHY documentation
From: Russell King (Oracle) @ 2026-02-18 13:15 UTC (permalink / raw)
To: Vinod Koul
Cc: Vladimir Oltean, Neil Armstrong, Jonathan Corbet, linux-doc,
linux-phy
In-Reply-To: <aY1f48Db7KeYRR87@vaman>
On Thu, Feb 12, 2026 at 10:36:43AM +0530, Vinod Koul wrote:
> On 11-02-26, 17:48, Vladimir Oltean wrote:
> > On Thu, Feb 05, 2026 at 02:56:15PM +0000, Russell King (Oracle) wrote:
> > > Update the generic PHY documentation as a result of the discussion for
> > > the s32g submission.
> > >
> > > Link: https://lore.kernel.org/r/aXtvDn_-pCuKPrnf@vaman
> > > Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> > > ---
> > > I didn't get any replies to my follow-up question to Vinod:
>
> Sorry to have missed that...
>
> > > Please also indicate in the documentation whether changing the submode
> > > of the serdes (particularly for ethernet) is permitted without doing a
> > > phy_power_down()..phy_power_up() dance around the phy_set_mode_ext()
> > > call.
> >
> > There's certainly nothing *not* permitting that call sequence.
>
> I agree on that. The documentation can be update to reflect that. Common
> logic would say that we should set things up before powering up, that
> should be the guidance here as well.
This is what my documentation patch does. It adds the possibility of
calling phy_set_mode*() before phy_power_on(), and recommends calling
phy_set_mode*() at that point, rather than the current situation where
the recommendation is after phy_power_on(). It leaves the possibility
of calling phy_set_mode*() afterwards in place.
It isn't clear to me what is required here - it seems that there is
disagreement between Vladimir and yourself, so I'm not planning to
submit an updated patch. Someone who knows what they're doing with
the generic phy stuff needs to propose a patch, and that ain't me.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/8] dt-bindings: pci: xilinx-nwl: Add resets
From: Manivannan Sadhasivam @ 2026-02-18 16:36 UTC (permalink / raw)
To: Sean Anderson
Cc: Pandey, Radhey Shyam, Laurent Pinchart, Vinod Koul,
linux-phy@lists.infradead.org, Krzysztof Wilczyński,
Lorenzo Pieralisi, linux-kernel@vger.kernel.org, Simek, Michal,
linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org,
Neil Armstrong, Rob Herring, Havalige, Thippeswamy, Bjorn Helgaas,
Conor Dooley, Krzysztof Kozlowski, devicetree@vger.kernel.org
In-Reply-To: <89516358-7b13-43ad-b303-1731f61d72e7@linux.dev>
On Thu, Feb 05, 2026 at 10:47:21AM -0500, Sean Anderson wrote:
> On 2/4/26 03:32, Pandey, Radhey Shyam wrote:
> > [AMD Official Use Only - AMD Internal Distribution Only]
> >
> >> -----Original Message-----
> >> From: Sean Anderson <sean.anderson@linux.dev>
> >> Sent: Tuesday, February 3, 2026 5:51 AM
> >> To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>; Vinod Koul
> >> <vkoul@kernel.org>; linux-phy@lists.infradead.org
> >> Cc: Krzysztof Wilczyński <kwilczynski@kernel.org>; Lorenzo Pieralisi
> >> <lpieralisi@kernel.org>; Pandey, Radhey Shyam
> >> <radhey.shyam.pandey@amd.com>; linux-kernel@vger.kernel.org; Simek, Michal
> >> <michal.simek@amd.com>; linux-arm-kernel@lists.infradead.org; linux-
> >> pci@vger.kernel.org; Neil Armstrong <neil.armstrong@linaro.org>; Rob Herring
> >> <robh@kernel.org>; Havalige, Thippeswamy <thippeswamy.havalige@amd.com>;
> >> Manivannan Sadhasivam <mani@kernel.org>; Bjorn Helgaas
> >> <bhelgaas@google.com>; Sean Anderson <sean.anderson@linux.dev>; Conor
> >> Dooley <conor+dt@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> >> devicetree@vger.kernel.org
> >> Subject: [PATCH 1/8] dt-bindings: pci: xilinx-nwl: Add resets
> >>
> >> Add resets so we can hold the bridge in reset while we perform phy calibration.
> >
> > Seems like this should a required property?
>
> It's optional as it does not exist in previous versions of the
> devicetree. In the past I have received pushback against making these
> sort of properties required.
>
> If the resets don't exist we just don't assert them and assume the
> bootloader has deasserted them.
>
If the resets are pretty much required for the hardware functionality, we can
mark them as required in the binding and accept the ABI breakage. This scenario
keeps coming with devicetree as the initial devicetree bindings lacked full
hardware description in most of the cases.
- Mani
> --Sean
>
> > Rest looks fine to me.
> >
> >>
> >> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> >> ---
> >>
> >> .../devicetree/bindings/pci/xlnx,nwl-pcie.yaml | 17 +++++++++++++++++
> >> 1 file changed, 17 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
> >> b/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
> >> index 9de3c09efb6e..7efb3dd9955f 100644
> >> --- a/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
> >> +++ b/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
> >> @@ -69,6 +69,18 @@ properties:
> >> power-domains:
> >> maxItems: 1
> >>
> >> + resets:
> >> + maxItems: 3
> >> +
> >> + reset-names:
> >> + items:
> >> + - description: APB register block reset
> >> + const: cfg
> >> + - description: AXI-PCIe bridge reset
> >> + const: bridge
> >> + - description: PCIe MAC reset
> >> + const: ctrl
> >> +
> >> iommus:
> >> maxItems: 1
> >>
> >> @@ -117,6 +129,7 @@ examples:
> >> #include <dt-bindings/interrupt-controller/irq.h>
> >> #include <dt-bindings/phy/phy.h>
> >> #include <dt-bindings/power/xlnx-zynqmp-power.h>
> >> + #include <dt-bindings/reset/xlnx-zynqmp-resets.h>
> >> soc {
> >> #address-cells = <2>;
> >> #size-cells = <2>;
> >> @@ -146,6 +159,10 @@ examples:
> >> msi-parent = <&nwl_pcie>;
> >> phys = <&psgtr 0 PHY_TYPE_PCIE 0 0>;
> >> power-domains = <&zynqmp_firmware PD_PCIE>;
> >> + resets = <&zynqmp_reset ZYNQMP_RESET_PCIE_CFG>,
> >> + <&zynqmp_reset ZYNQMP_RESET_PCIE_BRIDGE>,
> >> + <&zynqmp_reset ZYNQMP_RESET_PCIE_CTRL>;
> >> + reset-names = "cfg", "bridge", "ctrl";
> >> iommus = <&smmu 0x4d0>;
> >> pcie_intc: legacy-interrupt-controller {
> >> interrupt-controller;
> >> --
> >> 2.35.1.1320.gc452695387.dirty
> >
--
மணிவண்ணன் சதாசிவம்
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 7/8] PCI: xilinx-nwl: Reset the core during probe
From: Manivannan Sadhasivam @ 2026-02-18 16:42 UTC (permalink / raw)
To: Sean Anderson, Radhey Shyam Pandey, Michal Simek,
Thippeswamy Havalige
Cc: Laurent Pinchart, Vinod Koul, linux-phy,
Krzysztof Wilczyński, Lorenzo Pieralisi, linux-kernel,
linux-arm-kernel, linux-pci, Neil Armstrong, Rob Herring,
Bjorn Helgaas
In-Reply-To: <20260203002128.935842-8-sean.anderson@linux.dev>
On Mon, Feb 02, 2026 at 07:21:27PM -0500, Sean Anderson wrote:
> The PCIe core must be held in reset when initializing phys.
> Assert/deassert the appropriate resets.
>
> Resetting the core also resets the PCIe attributes to their default
> values, so initialize those too. For the most part the defaults are
> fine, but there are many attributes that default to an endpoint
> configuration and must be reprogrammed to function as a root device.
> We generally follow the controller programming sequence from UG1085.
>
> Xilinx was extremely imaginative and named all the registers ATTR_1,
> ATTR_2 etc. (with the fields organized in alphabetical order) so we
> follow the same convention. Only the fields are named, but sometimes a
> field is split across multiple registers. All the BARs are unused but
> some are repurposed as bridge registers when used as a root port.
>
Can someone from AMD/Xilinx review this patch?
- Mani
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> ---
>
> drivers/pci/controller/pcie-xilinx-nwl.c | 177 +++++++++++++++++++++++
> 1 file changed, 177 insertions(+)
>
> diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
> index 7cfdc21e6f40..b78fbad1efa5 100644
> --- a/drivers/pci/controller/pcie-xilinx-nwl.c
> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> @@ -22,6 +22,7 @@
> #include <linux/pci-ecam.h>
> #include <linux/phy/phy.h>
> #include <linux/platform_device.h>
> +#include <linux/reset.h>
> #include <linux/irqchip/chained_irq.h>
>
> #include "../pci.h"
> @@ -133,6 +134,54 @@
> #define CFG_DMA_REG_BAR GENMASK(2, 0)
> #define CFG_PCIE_CACHE GENMASK(7, 0)
>
> +#define PCIE_ATTR2_AER_CAP_PERMIT_ROOTERR_UPDATE BIT(0)
> +
> +#define PCIE_ATTR25_CPL_TIMEOUT_DISABLE_SUPPORTED BIT(9)
> +#define PCIE_ATTR25_INTX_IMPLEMENTED BIT(8)
> +#define PCIE_ATTR25_CLASS_CODE GENMASK(7, 0)
> +
> +#define PCIE_ATTR27_DEV_CAP_ENDPOINT_L1_LATENCY GENMASK(5, 3)
> +
> +#define PCIE_ATTR34_HEADER_TYPE GENMASK(7, 0)
> +
> +#define PCIE_ATTR35_LINK_CAP_DLL_ACTIVE_REPORTING BIT(15)
> +
> +#define PCIE_ATTR37_LINK_CAP_MAX_LINK_SPEED GENMASK(13, 10)
> +#define PCIE_ATTR37_LINK_CAP_MAX_LINK_SPEED_2_5 1
> +#define PCIE_ATTR37_LINK_CAP_MAX_LINK_SPEED_5_0 2
> +#define PCIE_ATTR37_LINK_CAP_BANDWIDTH_NOTIFICATION BIT(9)
> +
> +#define PCIE_ATTR50_CAP_DEVICE_PORT_TYPE GENMASK(7, 4)
> +#define PCIE_ATTR50_CAP_NEXTPTR GENMASK(15, 8)
> +
> +#define PCIE_ATTR53_CAP_NEXTPTR GENMASK(7, 0)
> +
> +#define PCIE_ATTR93_LL_REPLAY_TIMEOUT_EN BIT(15)
> +
> +#define PCIE_ATTR97_LTSSM_MAX_LINK_WIDTH GENMASK(11, 6)
> +#define PCIE_ATTR97_LINK_CAP_MAX_LINK_WIDTH GENMASK(5, 0)
> +
> +#define PCIE_ATTR100_UPSTREAM_FACING BIT(6)
> +
> +#define PCIE_ATTR101_EN_MSG_ROUTE GENMASK(15, 5)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_PME_TURN_OFF BIT(15)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_UNLOCK BIT(14)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_PME_TO_ACK BIT(13)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_PM_PME BIT(12)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_INTD BIT(11)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_INTC BIT(10)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_INTB BIT(9)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_INTA BIT(8)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_ERR_FATAL BIT(7)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_ERR_NONFATAL BIT(6)
> +#define PCIE_ATTR101_EN_MSG_ROUTE_ERR_COR BIT(5)
> +#define PCIE_ATTR101_DISABLE_BAR_FILTERING BIT(1)
> +
> +#define PCIE_ATTR106_VC0_TOTAL_CREDITS_NPH GENMASK(13, 7)
> +#define PCIE_ATTR106_VC0_TOTAL_CREDITS_CH GENMASK(6, 0)
> +
> +#define PCIE_ATTR109_VC0_TOTAL_CREDITS_PH GENMASK(6, 0)
> +
> #define INT_PCI_MSI_NR (2 * 32)
>
> /* Readin the PS_LINKUP */
> @@ -159,6 +208,7 @@ struct nwl_pcie {
> void __iomem *pcireg_base;
> void __iomem *ecam_base;
> struct phy *phy[4];
> + struct reset_control *ctrl_reset;
> phys_addr_t phys_breg_base; /* Physical Bridge Register Base */
> phys_addr_t phys_pcie_reg_base; /* Physical PCIe Controller Base */
> phys_addr_t phys_ecam_base; /* Physical Configuration Base */
> @@ -173,6 +223,115 @@ struct nwl_pcie {
> raw_spinlock_t leg_mask_lock;
> };
>
> +static void nwl_pcie_write_attr(struct nwl_pcie *pcie, u32 attr, u16 val)
> +{
> + writel(val, pcie->pcireg_base + attr * 4);
> +}
> +
> +static void nwl_pcie_modify_attr(struct nwl_pcie *pcie, u32 attr, u16 clear,
> + u16 set)
> +{
> + u32 val = readl(pcie->pcireg_base + attr * 4);
> +
> + nwl_pcie_write_attr(pcie, attr, (val & ~clear) | set);
> +}
> +
> +static void nwl_pcie_attr_init(struct nwl_pcie *pcie)
> +{
> + unsigned int width;
> +
> + for (width = ARRAY_SIZE(pcie->phy); width; width--)
> + if (pcie->phy[width - 1])
> + break;
> +
> + /* Set TLP header to type-1 */
> + nwl_pcie_modify_attr(pcie, 34, PCIE_ATTR34_HEADER_TYPE, PCI_HEADER_TYPE_BRIDGE);
> + nwl_pcie_modify_attr(pcie, 100, PCIE_ATTR100_UPSTREAM_FACING, 0);
> +
> + /* Disable BAR0/1 */
> + nwl_pcie_write_attr(pcie, 7, 0);
> + nwl_pcie_write_attr(pcie, 8, 0);
> + nwl_pcie_write_attr(pcie, 9, 0);
> + nwl_pcie_write_attr(pcie, 10, 0);
> + /* Enable primary/secondary/subordinate busses, disable latency timer */
> + nwl_pcie_write_attr(pcie, 11, 0xffff);
> + nwl_pcie_write_attr(pcie, 12, 0x00ff);
> + nwl_pcie_write_attr(pcie, 13, 0x0000); /* Disable I/O window */
> + nwl_pcie_write_attr(pcie, 14, 0x0000); /* Enable secondary status */
> + /* Enable memory window */
> + nwl_pcie_write_attr(pcie, 15, (u16)PCI_MEMORY_RANGE_MASK);
> + nwl_pcie_write_attr(pcie, 16, (u16)PCI_MEMORY_RANGE_MASK);
> + /* Enable 64-bit prefetchable window */
> + nwl_pcie_write_attr(pcie, 17,
> + (u16)PCI_PREF_RANGE_MASK | PCI_PREF_RANGE_TYPE_64);
> + nwl_pcie_write_attr(pcie, 18,
> + (u16)PCI_PREF_RANGE_MASK | PCI_PREF_RANGE_TYPE_64);
> + nwl_pcie_modify_attr(pcie, 101, 0, PCIE_ATTR101_DISABLE_BAR_FILTERING);
> +
> + /* Set class code to PCI_CLASS_BRIDGE_PCI_NORMAL */
> + nwl_pcie_write_attr(pcie, 24, PCI_CLASS_BRIDGE_PCI_NORMAL & 0xffff);
> + nwl_pcie_modify_attr(pcie, 25, PCIE_ATTR25_CLASS_CODE,
> + PCIE_ATTR25_CPL_TIMEOUT_DISABLE_SUPPORTED |
> + PCI_BASE_CLASS_BRIDGE);
> +
> + /* Enable PCIe capability */
> + nwl_pcie_modify_attr(pcie, 53, PCIE_ATTR53_CAP_NEXTPTR, 0x60);
> + nwl_pcie_modify_attr(pcie, 50,
> + PCIE_ATTR50_CAP_NEXTPTR |
> + PCIE_ATTR50_CAP_DEVICE_PORT_TYPE,
> + FIELD_PREP(PCIE_ATTR50_CAP_DEVICE_PORT_TYPE,
> + PCI_EXP_TYPE_ROOT_PORT));
> +
> + /* Disable MSI(-X) capability */
> + nwl_pcie_write_attr(pcie, 41, 0);
> + nwl_pcie_write_attr(pcie, 43, 0);
> + nwl_pcie_write_attr(pcie, 44, 0);
> + nwl_pcie_write_attr(pcie, 45, 0);
> + nwl_pcie_write_attr(pcie, 46, 0);
> + nwl_pcie_write_attr(pcie, 48, 0);
> +
> + /* Disable DSN capability */
> + nwl_pcie_write_attr(pcie, 31, 0);
> + nwl_pcie_write_attr(pcie, 82, PCI_CFG_SPACE_SIZE);
> +
> + /* Enable AER */
> + nwl_pcie_modify_attr(pcie, 2, 0,
> + PCIE_ATTR2_AER_CAP_PERMIT_ROOTERR_UPDATE);
> +
> + /* Disable L1 latency for root port */
> + nwl_pcie_modify_attr(pcie, 27,
> + PCIE_ATTR27_DEV_CAP_ENDPOINT_L1_LATENCY, 0);
> +
> + /* Enable bandwidth notification */
> + nwl_pcie_modify_attr(pcie, 37, 0,
> + PCIE_ATTR37_LINK_CAP_BANDWIDTH_NOTIFICATION);
> +
> + /* Set max link width */
> + nwl_pcie_write_attr(pcie, 97,
> + FIELD_PREP(PCIE_ATTR97_LTSSM_MAX_LINK_WIDTH, width) |
> + FIELD_PREP(PCIE_ATTR97_LINK_CAP_MAX_LINK_WIDTH, width));
> +
> + /* Route misc. TLPs to controller */
> + nwl_pcie_modify_attr(pcie, 101, PCIE_ATTR101_EN_MSG_ROUTE,
> + PCIE_ATTR101_EN_MSG_ROUTE_INTA |
> + PCIE_ATTR101_EN_MSG_ROUTE_INTB |
> + PCIE_ATTR101_EN_MSG_ROUTE_INTC |
> + PCIE_ATTR101_EN_MSG_ROUTE_INTD |
> + PCIE_ATTR101_EN_MSG_ROUTE_PM_PME |
> + PCIE_ATTR101_EN_MSG_ROUTE_PME_TO_ACK |
> + PCIE_ATTR101_EN_MSG_ROUTE_UNLOCK |
> + PCIE_ATTR101_EN_MSG_ROUTE_PME_TURN_OFF);
> +
> + /* Initialize completion credits */
> + nwl_pcie_write_attr(pcie, 105, 205); /* CD */
> + nwl_pcie_write_attr(pcie, 106,
> + FIELD_PREP(PCIE_ATTR106_VC0_TOTAL_CREDITS_NPH, 12) |
> + FIELD_PREP(PCIE_ATTR106_VC0_TOTAL_CREDITS_CH, 36));
> + nwl_pcie_write_attr(pcie, 107, 24); /* NPD */
> + nwl_pcie_write_attr(pcie, 108, 181); /* PD */
> + nwl_pcie_modify_attr(pcie, 109, PCIE_ATTR109_VC0_TOTAL_CREDITS_PH, 32);
> +}
> +
> static inline u32 nwl_bridge_readl(struct nwl_pcie *pcie, u32 off)
> {
> return readl(pcie->breg_base + off);
> @@ -806,6 +965,9 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
> irq_set_chained_handler_and_data(pcie->irq_intx,
> nwl_pcie_leg_handler, pcie);
>
> + pcie->ctrl_reset = devm_reset_control_get_optional(dev, "ctrl");
> + if (IS_ERR(pcie->ctrl_reset))
> + return PTR_ERR(pcie->ctrl_reset);
>
> for (i = 0; i < ARRAY_SIZE(pcie->phy); i++) {
> pcie->phy[i] = devm_of_phy_get_by_index(dev, dev->of_node, i);
> @@ -852,6 +1014,12 @@ static int nwl_pcie_probe(struct platform_device *pdev)
> if (IS_ERR(pcie->clk))
> return PTR_ERR(pcie->clk);
>
> + err = reset_control_assert(pcie->ctrl_reset);
> + if (err) {
> + dev_err(dev, "could not enter reset\n");
> + return err;
> + }
> +
> err = clk_prepare_enable(pcie->clk);
> if (err) {
> dev_err(dev, "can't enable PCIe ref clock\n");
> @@ -864,6 +1032,15 @@ static int nwl_pcie_probe(struct platform_device *pdev)
> goto err_clk;
> }
>
> + if (pcie->ctrl_reset)
> + nwl_pcie_attr_init(pcie);
> +
> + err = reset_control_deassert(pcie->ctrl_reset);
> + if (err) {
> + dev_err(dev, "could not release from reset\n");
> + goto err_phy_init;
> + }
> +
> err = nwl_pcie_phy_power_on(pcie);
> if (err) {
> dev_err(dev, "could not power on PHYs\n");
> --
> 2.35.1.1320.gc452695387.dirty
>
--
மணிவண்ணன் சதாசிவம்
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [REGRESSION] HDMI monitor not working on Radxa Rock 5B after phy rockchip samsung hdptx HDMI 2.1 FRL patchset
From: Cristian Ciocaltea @ 2026-02-18 20:15 UTC (permalink / raw)
To: dubito, Vinod Koul, Neil Armstrong, Heiko Stuebner, linux-phy,
linux-arm-kernel, linux-rockchip, linux-kernel, regressions
In-Reply-To: <26e31b3b-484f-433b-833f-c639ee437f63@collabora.com>
On 2/18/26 3:22 AM, Cristian Ciocaltea wrote:
> On 2/18/26 2:52 AM, Cristian Ciocaltea wrote:
>> Hi Thomas,
> [...]
>
>>
>> Sorry, I somehow missed the following warning message, though it has been
>> already present in all the logs you've sent to me so far:
>>
>> rockchip-hdptx-phy fed60000.phy: PLL locked by unknown consumer!
>>
>> That indicates the PHY has been preconfigured by an external component (e.g. the
>> bootloader), which is actually a scenario that I didn't verify.
>>
>> However, this just another way to expose a limitation of the current approach
>> for managing the TMDS character rate: done via the Common Clock Framework API
>> instead of the HDMI PHY configuration API.
>>
>> As a matter of fact, it was actually an item on my TODOs list for quite a while,
>> but blocked until recently due to several dependencies waiting to be merged
>> upstream.
>>
>> Hence I took the opportunity to finalize this task - please give the following
>> commits in my rk3588-hdmi-debug branch [2] a try:
>
> I've just realized I introduced a regression while doing some cleanup work, hence
> please ignore this until further notice.
I think I got this working properly now, at least it passes all the tests I
could run. The updated commits in [2] are:
fa7cd1e75aaa ("phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc")
8048db5544da ("phy: rockchip: samsung-hdptx: Exclusively use PHY config API for PLL changes")
0085a382dfd0 ("[DEBUG] drm/rockchip: Add HDMI verbose logging")
Regards,
Cristian
[2] https://gitlab.collabora.com/cristicc/linux-next/-/commits/rk3588-hdmi-debug
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [REGRESSION] HDMI monitor not working on Radxa Rock 5B after phy rockchip samsung hdptx HDMI 2.1 FRL patchset
From: 1und1 @ 2026-02-18 20:43 UTC (permalink / raw)
To: Cristian Ciocaltea, Vinod Koul, Neil Armstrong, Heiko Stuebner,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
regressions
In-Reply-To: <03b5f3d1-6db4-4835-b2a5-c22c1aa63825@collabora.com>
Hi Cristian,
Am Mittwoch, dem 18.02.2026 um 22:15 +0200 schrieb Cristian Ciocaltea:
> On 2/18/26 3:22 AM, Cristian Ciocaltea wrote:
> > On 2/18/26 2:52 AM, Cristian Ciocaltea wrote:
> > > Hi Thomas,
> > [...]
> >
> > >
> > > Sorry, I somehow missed the following warning message, though it has been
> > > already present in all the logs you've sent to me so far:
> > >
> > > rockchip-hdptx-phy fed60000.phy: PLL locked by unknown consumer!
> > >
> > > That indicates the PHY has been preconfigured by an external component
> > > (e.g. the
> > > bootloader), which is actually a scenario that I didn't verify.
> > >
> > > However, this just another way to expose a limitation of the current
> > > approach
> > > for managing the TMDS character rate: done via the Common Clock Framework
> > > API
> > > instead of the HDMI PHY configuration API.
> > >
> > > As a matter of fact, it was actually an item on my TODOs list for quite a
> > > while,
> > > but blocked until recently due to several dependencies waiting to be
> > > merged
> > > upstream.
> > >
> > > Hence I took the opportunity to finalize this task - please give the
> > > following
> > > commits in my rk3588-hdmi-debug branch [2] a try:
> >
> > I've just realized I introduced a regression while doing some cleanup work,
> > hence
> > please ignore this until further notice.
>
> I think I got this working properly now, at least it passes all the tests I
> could run. The updated commits in [2] are:
>
> fa7cd1e75aaa ("phy: rockchip: samsung-hdptx: Fix rate recalculation for high
> bpc")
> 8048db5544da ("phy: rockchip: samsung-hdptx: Exclusively use PHY config API
> for PLL changes")
> 0085a382dfd0 ("[DEBUG] drm/rockchip: Add HDMI verbose logging")
>
applying these commits solves my problems. I tested 1920x1080@60, 1920x1080@50
and 1920x1080@30. All work now. Thanks for the quick fix! And the positive side
effect seems to be that you can now take one of your old todos from your list.
Best regards,
Thomas
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [REGRESSION] HDMI monitor not working on Radxa Rock 5B after phy rockchip samsung hdptx HDMI 2.1 FRL patchset
From: Cristian Ciocaltea @ 2026-02-18 20:56 UTC (permalink / raw)
To: dubito, Vinod Koul, Neil Armstrong, Heiko Stuebner, linux-phy,
linux-arm-kernel, linux-rockchip, linux-kernel, regressions
In-Reply-To: <a3c3964e9e13c82d944fa1ee0acbb1a7806dd382.camel@online.de>
Hi Thomas,
On 2/18/26 10:43 PM, 1und1 wrote:
> Hi Cristian,
>
>
> Am Mittwoch, dem 18.02.2026 um 22:15 +0200 schrieb Cristian Ciocaltea:
>> On 2/18/26 3:22 AM, Cristian Ciocaltea wrote:
>>> On 2/18/26 2:52 AM, Cristian Ciocaltea wrote:
>>>> Hi Thomas,
>>> [...]
>>>
>>>>
>>>> Sorry, I somehow missed the following warning message, though it has been
>>>> already present in all the logs you've sent to me so far:
>>>>
>>>> rockchip-hdptx-phy fed60000.phy: PLL locked by unknown consumer!
>>>>
>>>> That indicates the PHY has been preconfigured by an external component
>>>> (e.g. the
>>>> bootloader), which is actually a scenario that I didn't verify.
>>>>
>>>> However, this just another way to expose a limitation of the current
>>>> approach
>>>> for managing the TMDS character rate: done via the Common Clock Framework
>>>> API
>>>> instead of the HDMI PHY configuration API.
>>>>
>>>> As a matter of fact, it was actually an item on my TODOs list for quite a
>>>> while,
>>>> but blocked until recently due to several dependencies waiting to be
>>>> merged
>>>> upstream.
>>>>
>>>> Hence I took the opportunity to finalize this task - please give the
>>>> following
>>>> commits in my rk3588-hdmi-debug branch [2] a try:
>>>
>>> I've just realized I introduced a regression while doing some cleanup work,
>>> hence
>>> please ignore this until further notice.
>>
>> I think I got this working properly now, at least it passes all the tests I
>> could run. The updated commits in [2] are:
>>
>> fa7cd1e75aaa ("phy: rockchip: samsung-hdptx: Fix rate recalculation for high
>> bpc")
>> 8048db5544da ("phy: rockchip: samsung-hdptx: Exclusively use PHY config API
>> for PLL changes")
>> 0085a382dfd0 ("[DEBUG] drm/rockchip: Add HDMI verbose logging")
>>
>
> applying these commits solves my problems. I tested 1920x1080@60, 1920x1080@50
> and 1920x1080@30. All work now. Thanks for the quick fix!
Thanks for the quick test!
I can add you to cc: when I submit the series, so that you may provide your
Tested-by tag if you'd like to.
> And the positive side> effect seems to be that you can now take one of your
> old todos from your list.
Indeed. :-)
Regards,
Cristian
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 2/4] arm64: dts: rockchip: Add USB2.0 PHY for RK3368
From: Johan Jonker @ 2026-02-18 22:52 UTC (permalink / raw)
To: Vladimir Oltean, WeiHao Li
Cc: heiko, robh, krzk+dt, conor+dt, linux-phy, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <20260212165550.mju3377fvphdsqoe@skbuf>
On 2/12/26 17:55, Vladimir Oltean wrote:
> On Tue, Sep 09, 2025 at 09:29:56PM +0800, WeiHao Li wrote:
>> RK3368 has one USB2.0 PHY with two ports, This adds device tree node for
>> it.
>>
>> Signed-off-by: WeiHao Li <cn.liweihao@gmail.com>
>> ---
>> arch/arm64/boot/dts/rockchip/rk3368.dtsi | 29 ++++++++++++++++++++++++
>> 1 file changed, 29 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
>> index 1b21787269..b09e431a64 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
>> @@ -766,11 +766,40 @@ cru: clock-controller@ff760000 {
>> grf: syscon@ff770000 {
>> compatible = "rockchip,rk3368-grf", "syscon", "simple-mfd";
>> reg = <0x0 0xff770000 0x0 0x1000>;
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>
> This introduces a device tree warning. You cannot mix nodes with no unit
> address (io-domains) with nodes with a unit address (usb2-phy@700) on
> the same hierarchical level. You have to pick a format and stick to it.
nope
Please add rockchip,rk3368-usb2phy to the list in grf.yaml in the same patch that you change rockchip,inno-usb2phy.yaml
Requires a bit of SOC and PHY maintainers coordination.
Place dt-binding compatible change patches before the patch that uses it. (patch 3 before patch 1)
due to: ./scripts/checkpatch.pl --strict
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/soc/rockchip/grf.yaml#n244
>
>>
>> io_domains: io-domains {
>> compatible = "rockchip,rk3368-io-voltage-domain";
>> status = "disabled";
>> };
>> +
>> + u2phy: usb2-phy@700 {
>> + compatible = "rockchip,rk3368-usb2phy";
>> + reg = <0x700 0x2c>;
>> + clocks = <&cru SCLK_OTGPHY0>;
>> + clock-names = "phyclk";
>> + clock-output-names = "usb480m_phy";
>> + #clock-cells = <0>;
>> + status = "disabled";
>> +
>> + u2phy_otg: otg-port {
>> + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
>> + <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
>> + <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> + interrupt-names = "otg-bvalid", "otg-id",
>> + "linestate";
>> + #phy-cells = <0>;
>> + status = "disabled";
>> + };
>> +
>> + u2phy_host: host-port {
>> + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> + interrupt-names = "linestate";
>> + #phy-cells = <0>;
>> + status = "disabled";
>> + };
>> + };
>> };
>>
>> wdt: watchdog@ff800000 {
>> --
>> 2.47.2
>>
>>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH AUTOSEL 6.19-6.12] phy: cadence-torrent: restore parent clock for refclk during resume
From: Sasha Levin @ 2026-02-19 2:03 UTC (permalink / raw)
To: patches, stable
Cc: Thomas Richard (TI.com), Neil Armstrong, Vinod Koul, Sasha Levin,
linux-phy, linux-kernel
In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org>
From: "Thomas Richard (TI.com)" <thomas.richard@bootlin.com>
[ Upstream commit 434e1a0ee145d0389b192252be4c993f86cf1134 ]
While suspend and resume, parent clock config for refclk was getting lost.
So save and restore it in suspend and resume operations.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
Link: https://patch.msgid.link/20251216-phy-cadence-torrent-resume-restore-refclk-parent-v3-1-8a7ed84b47e3@bootlin.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The verification confirms all the key elements:
1. **`cdns_torrent_refclk_driver_get_parent` and
`cdns_torrent_refclk_driver_set_parent`** exist and are well-defined
clock operations that read/write register fields for the clock mux
configuration.
2. **`CDNS_TORRENT_REFCLK_DRIVER`** is defined as index `0` in
`include/dt-bindings/phy/phy-cadence.h` and is used to index into
`clk_hw_data->hws[]`.
3. **Suspend/resume was introduced in commit `0da27ed080b2c`** (April
2024) by the same author (Thomas Richard). This means the
suspend/resume feature already exists in recent kernels, and this is
a bug fix to that existing feature.
4. All structures and fields referenced by the new code are actively
used in the driver.
## Verification Summary
- **Verified**: `cdns_torrent_refclk_driver_get_parent()` and
`cdns_torrent_refclk_driver_set_parent()` exist and operate on
register fields via regmap - these are the standard clock parent
operations.
- **Verified**: `CDNS_TORRENT_REFCLK_DRIVER` = 0, used as clock index in
`clk_hw_data->hws[]`.
- **Verified**: Suspend/resume functions were added in commit
`0da27ed080b2c` (April 2024) by the same author - this is a follow-up
fix to that code.
- **Verified**: The `parent_index` field and new suspend/resume helpers
only use existing, proven APIs.
- **Verified**: The patch is reviewed by Neil Armstrong and signed off
by the PHY subsystem maintainer Vinod Koul.
- **Note**: The suspend/resume support was introduced in v6.11 merge
window timeframe (April 2024), so this fix is relevant for stable
trees that include that commit.
## Classification
This is a **clear bug fix** for suspend/resume functionality:
- **Bug type**: State loss during power transitions (clock parent
configuration lost)
- **Impact**: PHY may not function correctly after resume, potentially
breaking PCIe, USB, or DisplayPort links
- **Scope**: Small, contained, single-driver fix (~22 lines)
- **Risk**: Very low - uses existing APIs, standard save/restore pattern
- **Dependencies**: Requires the suspend/resume support commit
(`0da27ed080b2c`) to be present in the stable tree
## Conclusion
This commit fixes a real suspend/resume bug where clock parent
configuration is lost, causing the PHY to malfunction after resume. The
fix is small, obviously correct, well-reviewed, and follows standard
kernel suspend/resume patterns. It meets all stable kernel criteria:
fixes a real bug, is small and contained, introduces no new features,
and has minimal regression risk.
The only consideration is that the stable tree must already contain the
initial suspend/resume support (commit `0da27ed080b2c` from ~April
2024), which limits this to newer stable branches (6.11+).
**YES**
drivers/phy/cadence/phy-cadence-torrent.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 37fa4bad6bd72..877f22177c699 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -397,6 +397,7 @@ struct cdns_torrent_refclk_driver {
struct clk_hw hw;
struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
struct clk_init_data clk_data;
+ u8 parent_index;
};
#define to_cdns_torrent_refclk_driver(_hw) \
@@ -3326,11 +3327,29 @@ static const struct cdns_torrent_vals sgmii_qsgmii_xcvr_diag_ln_vals = {
.num_regs = ARRAY_SIZE(sgmii_qsgmii_xcvr_diag_ln_regs),
};
+static void cdns_torrent_refclk_driver_suspend(struct cdns_torrent_phy *cdns_phy)
+{
+ struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER];
+ struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+
+ refclk_driver->parent_index = cdns_torrent_refclk_driver_get_parent(hw);
+}
+
+static int cdns_torrent_refclk_driver_resume(struct cdns_torrent_phy *cdns_phy)
+{
+ struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER];
+ struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+
+ return cdns_torrent_refclk_driver_set_parent(hw, refclk_driver->parent_index);
+}
+
static int cdns_torrent_phy_suspend_noirq(struct device *dev)
{
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
int i;
+ cdns_torrent_refclk_driver_suspend(cdns_phy);
+
reset_control_assert(cdns_phy->phy_rst);
reset_control_assert(cdns_phy->apb_rst);
for (i = 0; i < cdns_phy->nsubnodes; i++)
@@ -3352,6 +3371,10 @@ static int cdns_torrent_phy_resume_noirq(struct device *dev)
int node = cdns_phy->nsubnodes;
int ret, i;
+ ret = cdns_torrent_refclk_driver_resume(cdns_phy);
+ if (ret)
+ return ret;
+
ret = cdns_torrent_clk(cdns_phy);
if (ret)
return ret;
--
2.51.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH AUTOSEL 6.19-6.12] phy: ti: phy-j721e-wiz: restore mux selection during resume
From: Sasha Levin @ 2026-02-19 2:04 UTC (permalink / raw)
To: patches, stable
Cc: Thomas Richard (TI.com), Vinod Koul, Sasha Levin, linux-phy,
linux-kernel
In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org>
From: "Thomas Richard (TI.com)" <thomas.richard@bootlin.com>
[ Upstream commit 53f6240e88c9e8715e09fc19942f13450db4cb33 ]
While suspend and resume mux selection was getting lost. So save and
restore these values in suspend and resume operations.
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
Link: https://patch.msgid.link/20251216-phy-ti-phy-j721e-wiz-resume-restore-mux-sel-v1-1-771d564db966@bootlin.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Good. The current tree has the resume function but no suspend function
(the suspend slot is NULL), which matches the pre-patch state in the
diff.
## Analysis Summary
### What the commit does:
1. **Adds a new field** `mux_sel_status[WIZ_MUX_NUM_CLOCKS]` (3 ints) to
the `struct wiz` to store mux selection state.
2. **Adds a `wiz_suspend_noirq()` callback** that reads the 3 mux
selection values from hardware registers before suspend, saving them
in the new array.
3. **Modifies `wiz_resume_noirq()`** to write the saved mux selection
values back to hardware registers at the beginning of resume, before
the rest of the initialization.
4. **Updates the PM ops macro** from
`DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq)` to
`DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, wiz_suspend_noirq,
wiz_resume_noirq)`.
### Bug being fixed:
The mux clock selection values (which control how the SERDES reference
clocks are routed) are lost during suspend because the hardware state is
not preserved. On resume, `wiz_resume_noirq()` called `wiz_clock_init()`
and `wiz_init()`, but these re-initialize the clocks to default values
rather than restoring the user/driver-configured mux selections. This
means after resume, the SERDES PHY may not work correctly because the
clock routing is wrong.
### Classification: **Suspend/resume bug fix**
This is a real hardware bug that affects users who suspend and resume
systems using the TI J721E SERDES PHY (common in TI K3 SoC
automotive/industrial platforms). Without this fix, the PHY may not
function correctly after resume, potentially breaking network, PCIe,
USB, or other SERDES-based interfaces.
### Stable kernel rule compliance:
1. **Obviously correct and tested**: Simple save/restore pattern using
existing regmap_field_read/write APIs. The author works at Bootlin
for TI platforms.
2. **Fixes a real bug**: Mux selection lost after resume = broken PHY
after suspend/resume.
3. **Important issue**: Broken hardware functionality after
suspend/resume.
4. **Small and contained**: ~20 lines of new code, single file, simple
logic.
5. **No new features**: Restoring state that was lost is a bug fix, not
a feature.
### Risk assessment:
- **Very low risk**: The save/restore pattern is straightforward and
well-understood.
- **WIZ_MUX_NUM_CLOCKS is 3**: Only 3 register reads and 3 register
writes are added.
- **Uses existing regmap_field APIs**: No new infrastructure needed.
- **Only affects TI J721E platforms**: Cannot cause regressions on other
platforms.
- **Only affects suspend/resume path**: Cannot affect boot or normal
operation.
### Dependencies:
The resume support was added in commit `b5539abdd013f` (v6.11). The
`wiz_clock_init()` function split was in commit `3c4e13cf9ead7` (also
v6.11). So this fix is applicable to stable trees v6.11+, and possibly
v6.12.y and v6.13.y LTS trees if they exist.
## Verification
- **git log** confirmed the driver was first added in commit
`091876cc355d6` (phy: ti: j721e-wiz: Add support for WIZ module
present in TI J721E SoC)
- **git tag --contains** confirmed resume support (`b5539abdd013f`) was
introduced in v6.11
- **git tag --contains** confirmed `wiz_clock_init()` split
(`3c4e13cf9ead7`) was also introduced in v6.11
- **Grep for `WIZ_MUX_NUM_CLOCKS`** confirmed it is defined as 3, making
the save/restore loop iterate only 3 times
- **Grep for `mux_sel_status`** confirmed the field does not yet exist
in the working tree (commit not yet applied)
- **Grep for `wiz_resume_noirq`** confirmed the current code has resume
handler but NULL suspend handler, matching the pre-patch state
- **Read of the mux_sel_field usage** (lines 1031, 1056, 1172) confirmed
these fields control clock mux selection in the WIZ initialization
path
- **Unverified**: Whether any downstream users (e.g., Android, embedded
distros) have reported this specific suspend/resume issue. The commit
message states the problem directly but doesn't include "Reported-by:"
tags.
## Conclusion
This is a small, well-contained suspend/resume bug fix for the TI J721E
WIZ PHY driver. It fixes a real hardware issue where clock mux
selections are lost during suspend, rendering the SERDES PHY non-
functional after resume. The fix uses a standard save/restore pattern
with minimal code additions (~20 lines in a single file). The risk of
regression is very low since it only affects the suspend/resume path on
TI K3 platforms. It meets all stable kernel criteria.
**YES**
drivers/phy/ti/phy-j721e-wiz.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index a8b440c6c46bb..ba31b0a1f7f79 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -393,6 +393,7 @@ struct wiz {
struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS];
struct clk_onecell_data clk_data;
const struct wiz_data *data;
+ int mux_sel_status[WIZ_MUX_NUM_CLOCKS];
};
static int wiz_reset(struct wiz *wiz)
@@ -1654,11 +1655,25 @@ static void wiz_remove(struct platform_device *pdev)
pm_runtime_disable(dev);
}
+static int wiz_suspend_noirq(struct device *dev)
+{
+ struct wiz *wiz = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++)
+ regmap_field_read(wiz->mux_sel_field[i], &wiz->mux_sel_status[i]);
+
+ return 0;
+}
+
static int wiz_resume_noirq(struct device *dev)
{
struct device_node *node = dev->of_node;
struct wiz *wiz = dev_get_drvdata(dev);
- int ret;
+ int ret, i;
+
+ for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++)
+ regmap_field_write(wiz->mux_sel_field[i], wiz->mux_sel_status[i]);
/* Enable supplemental Control override if available */
if (wiz->sup_legacy_clk_override)
@@ -1680,7 +1695,7 @@ static int wiz_resume_noirq(struct device *dev)
return ret;
}
-static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq);
+static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, wiz_suspend_noirq, wiz_resume_noirq);
static struct platform_driver wiz_driver = {
.probe = wiz_probe,
--
2.51.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH AUTOSEL 6.19-5.10] phy: fsl-imx8mq-usb: disable bind/unbind platform driver feature
From: Sasha Levin @ 2026-02-19 2:04 UTC (permalink / raw)
To: patches, stable
Cc: Xu Yang, Frank Li, Vinod Koul, Sasha Levin, linux-phy, imx,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org>
From: Xu Yang <xu.yang_2@nxp.com>
[ Upstream commit 27ee0869d77b2cb404770ac49bdceae3aedf658b ]
Disabling PHYs in runtime usually causes the client with external abort
exception or similar issue due to lack of API to notify clients about PHY
removal. This patch removes the possibility to unbind i.MX PHY drivers in
runtime.
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260120111712.3159782-1-xu.yang_2@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Analysis Summary
### What the commit does
This commit adds `.suppress_bind_attrs = true` to the i.MX8MQ USB PHY
platform driver. This single line prevents the kernel from creating
`/sys/bus/platform/drivers/imx8mq-usb-phy/bind` and
`/sys/bus/platform/drivers/imx8mq-usb-phy/unbind` sysfs files, thereby
preventing runtime unbinding of the PHY driver.
### Problem being fixed
The commit message states that unbinding PHYs at runtime causes
"external abort exception or similar issue" because there is no API to
notify PHY clients about PHY removal. An external abort is a serious ARM
exception that typically results in a kernel crash/oops. If a user or
management tool writes to the `unbind` sysfs file for this PHY driver,
the USB controller client would try to access the now-missing PHY
resources, resulting in a crash.
### Stable kernel rules assessment
1. **Obviously correct and tested**: Yes - this is a well-established
one-line pattern used in 385+ files in the kernel. It's reviewed by
the PHY maintainer (Vinod Koul) and reviewed by Frank Li.
2. **Fixes a real bug**: Yes - runtime unbinding causes a crash
(external abort exception). This is a real, triggerable issue.
3. **Important issue**: Moderate - it prevents a crash, but only
triggered by explicit sysfs manipulation (not normal operation).
However, system management tools or user error could trigger this.
4. **Small and contained**: Yes - single one-line addition to a driver
struct.
5. **No new features**: Correct - this removes functionality (ability to
unbind), it doesn't add any.
### Risk assessment
- **Risk**: Extremely low. This is literally a single boolean field
being set in the driver struct. It only affects sysfs attributes. The
same pattern exists in 385+ other drivers.
- **Benefit**: Prevents a crash scenario when the PHY is unbound at
runtime.
- **Dependencies**: None - this is entirely self-contained.
### Concerns
- The bug is only triggerable by explicit sysfs manipulation (writing to
`/sys/bus/platform/drivers/imx8mq-usb-phy/unbind`), not by normal
system operation.
- The fix is a defensive measure rather than fixing a root cause in the
PHY framework. However, this is the standard kernel approach - the PHY
framework doesn't have removal notification, so drivers that can't
handle unbinding should suppress it.
- The change is straightforward and would apply cleanly to any stable
tree that has this driver.
### Classification
This falls into the **hardware quirk/workaround** category. It's a
defensive fix that prevents a crash scenario. While the trigger requires
explicit user action (sysfs unbind), this is a well-established pattern
in the kernel for exactly this purpose.
## Verification
- Verified `suppress_bind_attrs = true` is used in 385+ files across the
drivers/ directory via Grep search
- Verified 7 other PHY drivers (Samsung, HiSilicon) already use this
pattern
- Verified no other Freescale PHY drivers currently have this attribute
(this is the first)
- Verified via git log that similar commits exist for other subsystems
(gpio, perf)
- Verified via lore.kernel.org that the patch was reviewed by Frank Li
and accepted by PHY maintainer Vinod Koul
- Verified the commit message describes a real crash scenario (external
abort exception)
- Could NOT verify the specific crash reproduction steps (unverified,
but the mechanism is well-understood in the kernel community)
The fix is minimal (one line), extremely low risk, prevents a crash
scenario, uses a well-established kernel pattern, and was properly
reviewed. It meets all stable kernel criteria.
**YES**
drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index 91b3e62743d3a..b30d01f345d20 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -730,6 +730,7 @@ static struct platform_driver imx8mq_usb_phy_driver = {
.driver = {
.name = "imx8mq-usb-phy",
.of_match_table = imx8mq_usb_phy_of_match,
+ .suppress_bind_attrs = true,
}
};
module_platform_driver(imx8mq_usb_phy_driver);
--
2.51.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH AUTOSEL 6.19-5.15] phy: mvebu-cp110-utmi: fix dr_mode property read from dts
From: Sasha Levin @ 2026-02-19 2:04 UTC (permalink / raw)
To: patches, stable
Cc: Aleksandar Gerasimovski, Vinod Koul, Sasha Levin, linux-phy,
linux-kernel
In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org>
From: Aleksandar Gerasimovski <aleksandar.gerasimovski@belden.com>
[ Upstream commit e2ce913452ab56b3330539cc443b97b7ea8c3a1a ]
The problem with the current implementation is that it does not consider
that the USB controller can have multiple PHY handles with different
arguments count, as for example we have in our cn9131 based platform:
"phys = <&cp0_comphy1 0>, <&cp0_utmi0>;".
In such case calling "of_usb_get_dr_mode_by_phy" with -1 (no phy-cells)
leads to not proper phy detection, taking the "marvell,cp110-utmi-phy"
dts definition we can call the "of_usb_get_dr_mode_by_phy" with 0
(#phy-cells = <0>) and safely look for that phy.
Signed-off-by: Aleksandar Gerasimovski <aleksandar.gerasimovski@belden.com>
Link: https://patch.msgid.link/20260106150643.922110-1-aleksandar.gerasimovski@belden.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have a clear understanding of the bug. Let me verify the behavior
difference more carefully:
## Understanding the Bug
When `arg0 = -1`:
- The function uses `of_parse_phandle()` (line 303-306), which simply
returns the nth phandle node **without** parsing `#phy-cells`. It sets
`args.args_count = 0`.
- The matching at line 316-317: `args.np == np && (args.args_count == 0
|| args.args[0] == arg0)` — since `args_count = 0`, it matches on the
`np` comparison alone.
The problem: When the controller has `phys = <&cp0_comphy1 0>,
<&cp0_utmi0>;`, there are two phandle entries. The first (`cp0_comphy1`)
has `#phy-cells = <1>` (it takes argument `0`), and the second
(`cp0_utmi0`) has `#phy-cells = <0>`.
With `arg0 = -1`, `of_parse_phandle()` is used, which doesn't understand
`#phy-cells`. It simply iterates through raw phandle entries. Since
`cp0_comphy1` has an extra cell (`0`), `of_parse_phandle()` at index 0
returns `cp0_comphy1`, at index 1 it might return the `0` argument cell
(not a valid phandle) rather than `cp0_utmi0`. This leads to incorrect
PHY matching — the function can't properly find the UTMI PHY when mixed
`#phy-cells` counts are present.
With `arg0 = 0`:
- The function uses `of_parse_phandle_with_args()` (line 307-312), which
correctly parses `#phy-cells` for each phandle and properly skips over
argument cells. This means index 0 correctly refers to `cp0_comphy1`
(with its argument `0`) and index 1 correctly refers to `cp0_utmi0`.
- At line 316-317: for `cp0_utmi0`, `args.args_count = 0` (since `#phy-
cells = <0>`), so the match succeeds correctly.
This is a real functional bug fix — on platforms with mixed PHY types,
the UTMI PHY won't be correctly identified for its dual-role mode,
potentially causing the USB port to be configured incorrectly
(defaulting to HOST mode with a warning instead of detecting the correct
mode).
## Stable Kernel Criteria Assessment
1. **Fixes a real bug**: Yes — on cn9131-based platforms (and likely
others) with mixed PHY types, the UTMI PHY dr_mode detection fails,
leading to incorrect USB configuration.
2. **Obviously correct and tested**: The fix is a one-line change from
`-1` to `0`. The commit author is from Belden (likely has the
hardware). The change matches the documented `#phy-cells = <0>` for
this PHY type. Using `of_parse_phandle_with_args()` (triggered by
arg0 >= 0) is the correct approach when different PHYs have different
`#phy-cells` counts.
3. **Small and contained**: Single character change in one file. Minimal
risk.
4. **No new features**: This is purely a bug fix.
5. **User impact**: Without this fix, USB dual-role mode detection fails
on affected platforms. The PHY defaults to HOST mode when it might
need to be PERIPHERAL mode (or vice versa), which means USB
functionality is broken for those configurations.
## Risk Assessment
- **Risk**: Extremely low. The change from `-1` to `0` for a PHY with
`#phy-cells = <0>` is semantically equivalent for single-PHY
configurations. For multi-PHY configurations with mixed `#phy-cells`,
it's a correctness fix.
- **Regression potential**: Very low. The `of_parse_phandle_with_args()`
path is well-tested across the kernel. The only behavior change is
that mixed-PHY configurations now work correctly.
- **Scope**: Single driver, single line, Marvell ARM platform specific.
## Verification
- **Function `of_usb_get_dr_mode_by_phy` analyzed**: Read the
implementation at `drivers/usb/common/common.c:290-331`. Verified that
`arg0 = -1` uses `of_parse_phandle()` (no `#phy-cells` awareness)
while `arg0 >= 0` uses `of_parse_phandle_with_args()` (proper `#phy-
cells` parsing).
- **Device tree binding confirmed**: The Explore agent verified that
`Documentation/devicetree/bindings/phy/marvell,armada-cp110-utmi-
phy.yaml` specifies `#phy-cells: const: 0`, meaning arg0 = 0 is the
correct semantic match.
- **Driver history verified**: `git log` shows the driver was introduced
in commit `2fc989f74b8da` ("drivers: phy: add support for Armada CP110
UTMI PHY"), and the `-1` argument has been there since inception. The
file has had only 3 subsequent commits before this fix, none related
to dr_mode.
- **Matching logic verified**: At line 316-317, when `args.args_count ==
0` (which is the case for `#phy-cells = <0>`), the match succeeds on
`args.np == np` alone, so the value `0` doesn't cause a spurious
mismatch.
- **Bug mechanism verified**: With mixed `#phy-cells` (e.g., `phys =
<&cp0_comphy1 0>, <&cp0_utmi0>`), `of_parse_phandle()` (used with
arg0=-1) doesn't account for the argument cell `0` after
`cp0_comphy1`, leading to incorrect phandle indexing.
## Conclusion
This is a clear, minimal, one-line bug fix for incorrect device tree PHY
matching on Marvell CP110 UTMI platforms. It fixes a real functional
issue (incorrect USB dual-role mode detection) that affects users with
mixed-PHY configurations. The fix is obviously correct, has near-zero
regression risk, and follows the established pattern used by other PHY
drivers.
**YES**
drivers/phy/marvell/phy-mvebu-cp110-utmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
index 59903f86b13f5..dd3e515a8e865 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
@@ -338,7 +338,7 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
return -ENOMEM;
}
- port->dr_mode = of_usb_get_dr_mode_by_phy(child, -1);
+ port->dr_mode = of_usb_get_dr_mode_by_phy(child, 0);
if ((port->dr_mode != USB_DR_MODE_HOST) &&
(port->dr_mode != USB_DR_MODE_PERIPHERAL)) {
dev_err(&pdev->dev,
--
2.51.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH] phy: qcom: qmp-ufs: Fix SM8650 PCS table for Gear 4
From: Abel Vesa @ 2026-02-19 11:11 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Konrad Dybcio
Cc: Manivannan Sadhasivam, linux-arm-msm, linux-phy, linux-kernel,
stable, Nitin Rawat, Abel Vesa
According to internal documentation, on SM8650, when the PHY is configured
in Gear 4, the QPHY_V6_PCS_UFS_PLL_CNTL register needs to have the same
value as for Gear 5.
At the moment, there is no board that comes with a UFS 3.x device, so
this issue doesn't show up, but with the new Eliza SoC, which uses the
same init sequence as SM8650, on the MTP board, the link startup fails
with the current Gear 4 PCS table.
So fix that by moving the entry into the PCS generic table instead,
while keeping the value from Gear 5 configuration.
Cc: stable@vger.kernel.org # v6.10
Fixes: b9251e64a96f ("phy: qcom: qmp-ufs: update SM8650 tables for Gear 4 & 5")
Suggested-by: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index df138a5442eb..771bc7c2ab50 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -990,6 +990,7 @@ static const struct qmp_phy_init_tbl sm8650_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_PCS_CTRL1, 0xc1),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
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_POST_EMP_LVL_S4, 0x0e),
@@ -999,13 +1000,11 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_pcs[] = {
};
static const struct qmp_phy_init_tbl sm8650_ufsphy_g4_pcs[] = {
- QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13),
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 sm8650_ufsphy_g5_pcs[] = {
- QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d),
---
base-commit: 50f68cc7be0a2cbf54d8f6aaf17df32fb01acc3f
change-id: 20260219-phy-qcom-qmp-ufs-fix-sm8650-pcs-g4-table-9d1adf1508fb
Best regards,
--
Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+previous 0/9] net: stmmac: qcom-ethqos: further updates
From: Russell King (Oracle) @ 2026-02-19 12:49 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
This is part 2 of the qcom-ethqos series, building on the previous
series which can be found at
https://lore.kernel.org/r/aY0aJppQWUC52OUq@shell.armlinux.org.uk
This part of the series focuses on the generic PHY driver, but these
changes have dependencies on the ethernet driver, hence why
it will need to go via net-next. Furthermore, subsequent changes
depend on these patches.
The underlying ideas here are:
- get rid of the driver using phy_set_speed() with SPEED_1000 and
SPEED_2500 which makes no sense for an ethernet SerDes due to the
PCS 8B10B data encoding, which inflates the data rate at the SerDes
compared to the MAC.
- allow phy_power_on() / phy_set_mode*() to be called in any order.
I've included the set_clk_tx_rate() patch as that was tested, which
would make applying this series awkward to apply without it.
Mohd, please could you test this series - I'm hoping it will pass with
flying colours as there should be no change to the order in which we
program the hardware. Thanks.
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 52 +++++++-----------
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 62 +++++++++++++++++-----
2 files changed, 68 insertions(+), 46 deletions(-)
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH RFC net-next+ 1/9] net: stmmac: qcom-ethqos: convert to set_clk_tx_rate() method
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
Set the RGMII link clock using the set_clk_tx_rate() method rather than
coding it into the .fix_mac_speed() method. This simplifies ethqos's
ethqos_fix_mac_speed().
Tested-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 21 ++++++++++---------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 153f6abc77cd..ad5b5d950fff 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -103,7 +103,6 @@ struct qcom_ethqos {
void (*configure_func)(struct qcom_ethqos *ethqos,
phy_interface_t interface, int speed);
- unsigned int link_clk_rate;
struct clk *link_clk;
struct phy *serdes_phy;
int serdes_speed;
@@ -175,19 +174,20 @@ static void rgmii_dump(void *priv)
rgmii_readl(ethqos, EMAC_SYSTEM_LOW_POWER_DEBUG));
}
-static void
-ethqos_update_link_clk(struct qcom_ethqos *ethqos, int speed)
+static int ethqos_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
+ phy_interface_t interface, int speed)
{
+ struct qcom_ethqos *ethqos = bsp_priv;
long rate;
- if (!phy_interface_mode_is_rgmii(ethqos->phy_mode))
- return;
+ if (!phy_interface_mode_is_rgmii(interface))
+ return 0;
rate = rgmii_clock(speed);
- if (rate > 0)
- ethqos->link_clk_rate = rate * 2;
+ if (rate < 0)
+ return rate;
- clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);
+ return clk_set_rate(ethqos->link_clk, rate * 2);
}
static void
@@ -643,7 +643,6 @@ static void ethqos_fix_mac_speed(void *priv, phy_interface_t interface,
{
struct qcom_ethqos *ethqos = priv;
- ethqos_update_link_clk(ethqos, speed);
ethqos_configure(ethqos, interface, speed);
}
@@ -821,12 +820,14 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
"Failed to get serdes phy\n");
ethqos->serdes_speed = SPEED_1000;
- ethqos_update_link_clk(ethqos, SPEED_1000);
+ ethqos_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
+ SPEED_1000);
qcom_ethqos_set_sgmii_loopback(ethqos, true);
ethqos_set_func_clk_en(ethqos);
plat_dat->bsp_priv = ethqos;
+ plat_dat->set_clk_tx_rate = ethqos_set_clk_tx_rate;
plat_dat->fix_mac_speed = ethqos_fix_mac_speed;
plat_dat->dump_debug_regs = rgmii_dump;
plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 2/9] net: stmmac: qcom-ethqos: move ethqos_set_serdes_speed()
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
Combine ethqos_set_serdes_speed() with ethqos_mac_finish_serdes() to
simplify the code.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index ad5b5d950fff..57cbe800f652 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -591,14 +591,6 @@ static void ethqos_configure_rgmii(struct qcom_ethqos *ethqos,
ethqos_rgmii_macro_init(ethqos, speed);
}
-static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
-{
- if (ethqos->serdes_speed != speed) {
- phy_set_speed(ethqos->serdes_phy, speed);
- ethqos->serdes_speed = speed;
- }
-}
-
static void ethqos_pcs_set_inband(struct stmmac_priv *priv, bool enable)
{
stmmac_pcs_ctrl_ane(priv, enable, 0);
@@ -683,15 +675,23 @@ static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv,
phy_interface_t interface)
{
struct qcom_ethqos *ethqos = priv;
+ int speed, ret = 0;
qcom_ethqos_set_sgmii_loopback(ethqos, false);
+ speed = SPEED_UNKNOWN;
if (interface == PHY_INTERFACE_MODE_SGMII)
- ethqos_set_serdes_speed(ethqos, SPEED_1000);
+ speed = SPEED_1000;
else if (interface == PHY_INTERFACE_MODE_2500BASEX)
- ethqos_set_serdes_speed(ethqos, SPEED_2500);
+ speed = SPEED_2500;
- return 0;
+ if (speed != SPEED_UNKNOWN && speed != ethqos->serdes_speed) {
+ ret = phy_set_speed(ethqos->serdes_phy, speed);
+ if (ret == 0)
+ ethqos->serdes_speed = speed;
+ }
+
+ return ret;
}
static int ethqos_clks_config(void *priv, bool enabled)
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 3/9] phy: qcom-sgmii-eth: add .set_mode() and .validate() methods
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
qcom-sgmii-eth is an Ethernet SerDes supporting only Ethernet mode
using SGMII, 1000BASE-X and 2500BASE-X.
Add an implementation of the .set_mode() method, which can be used
instead of or as well as the .set_speed() method. The Ethernet
interface modes mentioned above all have a fixed data rate, so
setting the mode is sufficient to fully specify the operating
parameters.
Add an implementation of the .validate() method, which will be
necessary to allow discovery of the SerDes capabilities for platform
independent SerDes support in the stmmac network driver.
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 43 +++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 5b1c82459c12..4ea3dce7719f 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -7,6 +7,7 @@
#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -286,6 +287,37 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
return 0;
}
+static int qcom_dwmac_sgmii_phy_speed(enum phy_mode mode, int submode)
+{
+ if (mode != PHY_MODE_ETHERNET)
+ return -EINVAL;
+
+ if (submode == PHY_INTERFACE_MODE_SGMII ||
+ submode == PHY_INTERFACE_MODE_1000BASEX)
+ return SPEED_1000;
+
+ if (submode == PHY_INTERFACE_MODE_2500BASEX)
+ return SPEED_2500;
+
+ return -EINVAL;
+}
+
+static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode,
+ int submode)
+{
+ struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
+ int speed;
+
+ speed = qcom_dwmac_sgmii_phy_speed(mode, submode);
+ if (speed < 0)
+ return speed;
+
+ if (speed != data->speed)
+ data->speed = speed;
+
+ return qcom_dwmac_sgmii_phy_calibrate(phy);
+}
+
static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
@@ -296,10 +328,21 @@ static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed)
return qcom_dwmac_sgmii_phy_calibrate(phy);
}
+static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
+ int submode,
+ union phy_configure_opts *opts)
+{
+ int ret = qcom_dwmac_sgmii_phy_speed(mode, submode);
+
+ return ret < 0 ? ret : 0;
+}
+
static const struct phy_ops qcom_dwmac_sgmii_phy_ops = {
.power_on = qcom_dwmac_sgmii_phy_power_on,
.power_off = qcom_dwmac_sgmii_phy_power_off,
+ .set_mode = qcom_dwmac_sgmii_phy_set_mode,
.set_speed = qcom_dwmac_sgmii_phy_set_speed,
+ .validate = qcom_dwmac_sgmii_phy_validate,
.calibrate = qcom_dwmac_sgmii_phy_calibrate,
.owner = THIS_MODULE,
};
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 4/9] net: stmmac: qcom-ethqos: convert to use phy_set_mode_ext()
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
qcom-sgmii-eth now accepts the phy_set_mode*() calls to configure the
SerDes, taking a PHY interface mode rather than a speed. This allows
the elimination of the interface mode to speed conversion in
ethqos_mac_finish_serdes().
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 23 ++++++++-----------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 57cbe800f652..65316c603cae 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -105,7 +105,7 @@ struct qcom_ethqos {
struct clk *link_clk;
struct phy *serdes_phy;
- int serdes_speed;
+ phy_interface_t serdes_mode;
phy_interface_t phy_mode;
const struct ethqos_emac_por *rgmii_por;
@@ -653,7 +653,8 @@ static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)
return ret;
}
- ret = phy_set_speed(ethqos->serdes_phy, ethqos->serdes_speed);
+ ret = phy_set_mode(ethqos->serdes_phy, PHY_MODE_ETHERNET,
+ ethqos->serdes_mode);
if (ret) {
phy_power_off(ethqos->serdes_phy);
phy_exit(ethqos->serdes_phy);
@@ -675,20 +676,16 @@ static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv,
phy_interface_t interface)
{
struct qcom_ethqos *ethqos = priv;
- int speed, ret = 0;
+ int ret = 0;
qcom_ethqos_set_sgmii_loopback(ethqos, false);
- speed = SPEED_UNKNOWN;
- if (interface == PHY_INTERFACE_MODE_SGMII)
- speed = SPEED_1000;
- else if (interface == PHY_INTERFACE_MODE_2500BASEX)
- speed = SPEED_2500;
-
- if (speed != SPEED_UNKNOWN && speed != ethqos->serdes_speed) {
- ret = phy_set_speed(ethqos->serdes_phy, speed);
+ if (interface == PHY_INTERFACE_MODE_SGMII ||
+ interface == PHY_INTERFACE_MODE_2500BASEX) {
+ ret = phy_set_mode(ethqos->serdes_phy, PHY_MODE_ETHERNET,
+ interface);
if (ret == 0)
- ethqos->serdes_speed = speed;
+ ethqos->serdes_mode = interface;
}
return ret;
@@ -819,7 +816,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy),
"Failed to get serdes phy\n");
- ethqos->serdes_speed = SPEED_1000;
ethqos_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
SPEED_1000);
@@ -843,6 +839,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
plat_dat->host_dma_width = data->dma_addr_width;
if (ethqos->serdes_phy) {
+ ethqos->serdes_mode = PHY_INTERFACE_MODE_SGMII;
plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
}
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 5/9] phy: qcom-sgmii-eth: remove .set_speed() implementation
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
Now that the qcom-ethqos driver has migrated to use phy_set_mode_ext()
rather than phy_set_speed() to configure the SerDes, the support for
phy_set_speed() is now obsolete. Remove support for this method.
Using the MAC speed for the SerDes is never correct due to the PCS
encoding. For SGMII and 2500BASE-X, the PCS uses 8B10B encoding, and
so:
MAC rate * PCS output bits / PCS input bits = SerDes rate
1000M * 10 / 8 = 1250M
2500M * 10 / 8 = 3125M
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 4ea3dce7719f..dcfdb7d0e8ea 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -318,16 +318,6 @@ static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode,
return qcom_dwmac_sgmii_phy_calibrate(phy);
}
-static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed)
-{
- struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
-
- if (speed != data->speed)
- data->speed = speed;
-
- return qcom_dwmac_sgmii_phy_calibrate(phy);
-}
-
static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
int submode,
union phy_configure_opts *opts)
@@ -341,7 +331,6 @@ static const struct phy_ops qcom_dwmac_sgmii_phy_ops = {
.power_on = qcom_dwmac_sgmii_phy_power_on,
.power_off = qcom_dwmac_sgmii_phy_power_off,
.set_mode = qcom_dwmac_sgmii_phy_set_mode,
- .set_speed = qcom_dwmac_sgmii_phy_set_speed,
.validate = qcom_dwmac_sgmii_phy_validate,
.calibrate = qcom_dwmac_sgmii_phy_calibrate,
.owner = THIS_MODULE,
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 6/9] phy: qcom-sgmii-eth: use PHY interface mode for SerDes settings
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
As established in the previous commit, using SPEED_1000 and SPEED_2500
does not make sense for a SerDes due to the PCS encoding that is used
over the SerDes link, which inflates the data rate at the SerDes. Thus,
the use of these constants in a SerDes driver is incorrect.
Since qcom-sgmii-eth no longer implements phy_set_speed(), but instead
uses the PHY interface mode passed via the .set_mode() method, convert
the driver to use the PHY interface mode internally to decide whether
to configure the SerDes for 1.25Gbps or 3.125Gbps mode.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 41 ++++++++++++-----------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index dcfdb7d0e8ea..58ff15601206 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -29,7 +29,7 @@
struct qcom_dwmac_sgmii_phy_data {
struct regmap *regmap;
struct clk *refclk;
- int speed;
+ phy_interface_t interface;
};
static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
@@ -223,15 +223,18 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
struct device *dev = phy->dev.parent;
- switch (data->speed) {
- case SPEED_10:
- case SPEED_100:
- case SPEED_1000:
+ switch (data->interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ /* 1.25Gbps mode */
qcom_dwmac_sgmii_phy_init_1g(data->regmap);
break;
- case SPEED_2500:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ /* 3.125Gbps mode */
qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
break;
+ default:
+ return -EINVAL;
}
if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
@@ -287,17 +290,15 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
return 0;
}
-static int qcom_dwmac_sgmii_phy_speed(enum phy_mode mode, int submode)
+static int qcom_dwmac_sgmii_phy_interface(enum phy_mode mode, int submode)
{
if (mode != PHY_MODE_ETHERNET)
return -EINVAL;
if (submode == PHY_INTERFACE_MODE_SGMII ||
- submode == PHY_INTERFACE_MODE_1000BASEX)
- return SPEED_1000;
-
- if (submode == PHY_INTERFACE_MODE_2500BASEX)
- return SPEED_2500;
+ submode == PHY_INTERFACE_MODE_1000BASEX ||
+ submode == PHY_INTERFACE_MODE_2500BASEX)
+ return submode;
return -EINVAL;
}
@@ -306,14 +307,14 @@ static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode,
int submode)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
- int speed;
+ int interface;
- speed = qcom_dwmac_sgmii_phy_speed(mode, submode);
- if (speed < 0)
- return speed;
+ interface = qcom_dwmac_sgmii_phy_interface(mode, submode);
+ if (interface < 0)
+ return interface;
- if (speed != data->speed)
- data->speed = speed;
+ if (interface != data->interface)
+ data->interface = interface;
return qcom_dwmac_sgmii_phy_calibrate(phy);
}
@@ -322,7 +323,7 @@ static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
int submode,
union phy_configure_opts *opts)
{
- int ret = qcom_dwmac_sgmii_phy_speed(mode, submode);
+ int ret = qcom_dwmac_sgmii_phy_interface(mode, submode);
return ret < 0 ? ret : 0;
}
@@ -356,7 +357,7 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- data->speed = SPEED_10;
+ data->interface = PHY_INTERFACE_MODE_SGMII;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 7/9] phy: qcom-sgmii-eth: remove qcom_dwmac_sgmii_phy_interface()
From: Russell King (Oracle) @ 2026-02-19 12:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
Now that qcom_dwmac_sgmii_phy_interface() only serves to validate the
passed interface mode, combine it with qcom_dwmac_sgmii_phy_validate(),
and use qcom_dwmac_sgmii_phy_validate() to validate the mode in
qcom_dwmac_sgmii_phy_set_mode().
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 27 +++++++++--------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 58ff15601206..6332ff291fdf 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -290,7 +290,9 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
return 0;
}
-static int qcom_dwmac_sgmii_phy_interface(enum phy_mode mode, int submode)
+static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
+ int submode,
+ union phy_configure_opts *opts)
{
if (mode != PHY_MODE_ETHERNET)
return -EINVAL;
@@ -298,7 +300,7 @@ static int qcom_dwmac_sgmii_phy_interface(enum phy_mode mode, int submode)
if (submode == PHY_INTERFACE_MODE_SGMII ||
submode == PHY_INTERFACE_MODE_1000BASEX ||
submode == PHY_INTERFACE_MODE_2500BASEX)
- return submode;
+ return 0;
return -EINVAL;
}
@@ -307,27 +309,18 @@ static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode,
int submode)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
- int interface;
+ int ret;
- interface = qcom_dwmac_sgmii_phy_interface(mode, submode);
- if (interface < 0)
- return interface;
+ ret = qcom_dwmac_sgmii_phy_validate(phy, mode, submode, NULL);
+ if (ret)
+ return ret;
- if (interface != data->interface)
- data->interface = interface;
+ if (submode != data->interface)
+ data->interface = submode;
return qcom_dwmac_sgmii_phy_calibrate(phy);
}
-static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
- int submode,
- union phy_configure_opts *opts)
-{
- int ret = qcom_dwmac_sgmii_phy_interface(mode, submode);
-
- return ret < 0 ? ret : 0;
-}
-
static const struct phy_ops qcom_dwmac_sgmii_phy_ops = {
.power_on = qcom_dwmac_sgmii_phy_power_on,
.power_off = qcom_dwmac_sgmii_phy_power_off,
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RFC net-next+ 8/9] phy: qcom-sgmii-eth: relax order of .power_on() vs .set_mode*()
From: Russell King (Oracle) @ 2026-02-19 12:51 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-phy,
linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
Paolo Abeni, Vinod Koul
In-Reply-To: <aZcGxDBwfMXHbo_O@shell.armlinux.org.uk>
Allow any order of the .power_on() and .set_mode*() methods as per the
recent discussion. This means phy_power_on() with this SerDes will now
restore the previous setup without requiring a subsequent
phy_set_mode*() call.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 6332ff291fdf..f48faa2929a6 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -271,8 +271,17 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
+ int ret;
+
+ ret = clk_prepare_enable(data->refclk);
+ if (ret < 0)
+ return ret;
- return clk_prepare_enable(data->refclk);
+ ret = qcom_dwmac_sgmii_phy_calibrate(phy);
+ if (ret < 0)
+ clk_disable_unprepare(data->refclk);
+
+ return ret;
}
static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
@@ -318,6 +327,9 @@ static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode,
if (submode != data->interface)
data->interface = submode;
+ if (phy->power_count == 0)
+ return 0;
+
return qcom_dwmac_sgmii_phy_calibrate(phy);
}
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
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