Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] MAINTAINERS: Hand over phy-zynqmp to Tomi Valkeinen
From: Vinod Koul @ 2026-05-19 10:48 UTC (permalink / raw)
  To: linux-phy, linux-kernel, Laurent Pinchart
  Cc: Tomi Valkeinen, neil.armstrong, michal.simek, Radhey Shyam Pandey
In-Reply-To: <20260519082253.40142-1-laurent.pinchart@ideasonboard.com>


On Tue, 19 May 2026 10:22:53 +0200, Laurent Pinchart wrote:
> I volunteered to maintain the phy-zynqmp driver as part of my work on
> the ZynqMP DPSUB driver. Now that Tomi has taken over the DPSUB, it
> makes sense for him to handle the phy-zynqmp driver as well.
> 
> 

Applied, thanks!

[1/1] MAINTAINERS: Hand over phy-zynqmp to Tomi Valkeinen
      commit: 293e19f416fa3f233a2fb013258f7abcb39ad6ed

Best regards,
-- 
~Vinod



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v4 linux-phy 0/3] phy: ti: add driver for TI DS125DF111 Dual-Channel Retimer
From: Vinod Koul @ 2026-05-19 10:48 UTC (permalink / raw)
  To: neil.armstrong, robh, krzk+dt, conor+dt, johan, linux-phy,
	Ioana Ciornei
  Cc: devicetree, linux-kernel
In-Reply-To: <20260518142026.3098496-1-ioana.ciornei@nxp.com>


On Mon, 18 May 2026 17:20:23 +0300, Ioana Ciornei wrote:
> This patch set adds a generic PHY driver and the corresponding DT
> binding for the TI DS125DF111 Dual-Channel retimer. The datasheet on
> which this driver was based on can be found at -
> https://www.ti.com/lit/gpn/DS125DF111.
> 
> A separate generic PHY is registered for each of the two channels of the
> retimer, so consumers can drive each channel independently. This allows
> for independent control of the channels, which is especially important
> since each channel can be routed to different SerDes lanes and it is not
> guaranteed that the same retimer will do both directions of SerDes lane.
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: phy: add PHY bindings for the TI DS125DF111 Retimer PHY
      commit: a62d9440ebbce3d9f0bd6c346a7fda2a53726850
[2/3] phy: ti: alphabetically sort Kconfig and Makefile
      commit: 711f64979e500799b27b33a8f030e2fd939fd07f
[3/3] phy: ti: add PHY driver for TI DS125DF111 Dual-Channel Retimer
      commit: 9bf5c16a6e63ebf2803deb32ba984a7fcf2c5ed7

Best regards,
-- 
~Vinod



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3] phy: rockchip: naneng-combphy: Consolidate SSC configuration
From: Vinod Koul @ 2026-05-19 10:48 UTC (permalink / raw)
  To: Shawn Lin; +Cc: linux-rockchip, linux-phy, Heiko Stuebner, Neil Armstrong
In-Reply-To: <1777251433-110466-1-git-send-email-shawn.lin@rock-chips.com>


On Mon, 27 Apr 2026 08:57:13 +0800, Shawn Lin wrote:
> The PCIe SSC configuration for the RK3588 and RK3576 SoCs required
> additional tuning which is missing. When adding these same SSC
> configurations for both of these two SoCs, as well as upcoming
> platforms, it's obvious the SSC setup code was largely duplicated
> across the platform-specific configuration functions. This becomes
> harder to maintain as more platforms are added.
> 
> [...]

Applied, thanks!

[1/1] phy: rockchip: naneng-combphy: Consolidate SSC configuration
      commit: 0b31f297557fff0941769e8257198151a0fbe8bf

Best regards,
-- 
~Vinod



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3] phy: qcom: qmp-combo: Move pipe_clk on/off to common
From: Vinod Koul @ 2026-05-19 10:48 UTC (permalink / raw)
  To: Konrad Dybcio, Kishon Vijay Abraham I, Bjorn Andersson,
	Wesley Cheng, Neil Armstrong, Val Packett
  Cc: Dmitry Baryshkov, linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <20260304190827.176988-1-val@packett.cool>


On Wed, 04 Mar 2026 16:06:23 -0300, Val Packett wrote:
> Keep the USB pipe clock working when the phy is in DP-only mode, because
> the dwc controller still needs it for USB 2.0 over the same Type-C port.
> 
> Tested with the BenQ RD280UA monitor which has a downstream-facing port
> for data passthrough that's manually switchable between USB 2 and 3,
> corresponding to 4-lane and 2-lane DP respectively.
> 
> [...]

Applied, thanks!

[1/1] phy: qcom: qmp-combo: Move pipe_clk on/off to common
      commit: f546912bcac6463a22c5825e27a7952f8b48c887

Best regards,
-- 
~Vinod



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH] phy: qcom: qmp-usbc: Fix out-of-bounds array access in dp swing config
From: Vinod Koul @ 2026-05-19 10:43 UTC (permalink / raw)
  To: Neil Armstrong, Dmitry Baryshkov, Xiangxu Yin
  Cc: linux-arm-msm, linux-phy, linux-kernel, fange.zhang, yongxing.mou,
	li.liu, tingwei.zhang, Konrad Dybcio, Dan Carpenter
In-Reply-To: <20260227-master-v1-1-8d91b9407fdb@oss.qualcomm.com>


On Fri, 27 Feb 2026 20:15:01 +0800, Xiangxu Yin wrote:
> swing_tbl and pre_emphasis_tbl are 4x4 arrays (valid indices 0-3), but
> the boundary check uses "> 4" instead of ">= 4", allowing index 4 to
> cause an out-of-bounds access.
> 
> 

Applied, thanks!

[1/1] phy: qcom: qmp-usbc: Fix out-of-bounds array access in dp swing config
      commit: ea17fc4d7dc2ba6459b1a318962960520201baf1

Best regards,
-- 
~Vinod



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3 phy-next 2/2] phy: ti: add PHY driver for TI DS125DF111 Dual-Channel Retimer
From: Ioana Ciornei @ 2026-05-19 10:36 UTC (permalink / raw)
  To: Vinod Koul
  Cc: neil.armstrong, robh, krzk+dt, conor+dt, johan, linux-phy,
	devicetree, linux-kernel
In-Reply-To: <agw8GeTLAZJ8XU8-@vaman>

On Tue, May 19, 2026 at 04:01:53PM +0530, Vinod Koul wrote:
> On 18-05-26, 10:29, Ioana Ciornei wrote:
> > On Sun, May 17, 2026 at 10:07:56PM +0530, Vinod Koul wrote:
> > > On 16-05-26, 09:03, Ioana Ciornei wrote:
> > > > Add a generic PHY driver for the TI DS125DF111 Multi-Protocol
> > > > Dual-Channel Retimer. The driver currently supports only 10G and 1G link
> > > > speeds but it can easily extended to also cover other usecases.
> > > > 
> > > > Since the available datasheet (https://www.ti.com/lit/gpn/DS125DF111)
> > > > does not name the registers, the name for the macros were determined by
> > > > their usage pattern.
> > > > 
> > > > A PHY device is created for each of the two channels present on the
> > > > retimer. This allows for independent configuration of the two channels.
> > > > This capability is especially important on retimers which have more than
> > > > 2 channels that can be, depending on the board design, connected in
> > > > multiple different ways to the SerDes lanes.
> > > > 
> > > > Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> > > > ---
> > > > Changes in v3:
> > > > - Use reverse Christmas tree ordering
> > > > - Print a symbolic description in case of error
> > > > - Some words do not need to be capitalized
> > > > - Remove duplicated exit code path
> > > > - Return -EINVAL in case of unsupported submode received in .set_mode()
> > > > - Add a .validate() callback
> > > > - Remove comma after sentinel entry
> > > > - Add a ds125df111_rmw() helper
> > > > - Use read_poll_timeout() to wait for channel reset to complete
> > > > 
> > > > Changes in v2:
> > > > - Explicitly include all the needed headers
> > > > - Change ds125df111_xlate() so that it returns an error if args_count is
> > > > not exactly 1
> > > > - Add a MAINTAINERS entry
> > > > ---

(...)

> > Now that I actually tried to make the change that you requested, I
> > realised that the Kconfig is not following any alphabetical order. And
> > neither does the Makefile.
> > 
> > Do you still want me to move the entries?
> 
> Yes please. I will sort this one later in the cycle again!

I did the sorting myself for the entire TI Kconfig and Makefile and sent
a new version: https://lore.kernel.org/all/20260518142026.3098496-1-ioana.ciornei@nxp.com/


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3 phy-next 2/2] phy: ti: add PHY driver for TI DS125DF111 Dual-Channel Retimer
From: Vinod Koul @ 2026-05-19 10:31 UTC (permalink / raw)
  To: Ioana Ciornei
  Cc: neil.armstrong, robh, krzk+dt, conor+dt, johan, linux-phy,
	devicetree, linux-kernel
In-Reply-To: <fkosq3es6lqzabowzpppgsal4lhctb4qyr6ypmazm7vwekd7ix@elffqa6kx5jp>

On 18-05-26, 10:29, Ioana Ciornei wrote:
> On Sun, May 17, 2026 at 10:07:56PM +0530, Vinod Koul wrote:
> > On 16-05-26, 09:03, Ioana Ciornei wrote:
> > > Add a generic PHY driver for the TI DS125DF111 Multi-Protocol
> > > Dual-Channel Retimer. The driver currently supports only 10G and 1G link
> > > speeds but it can easily extended to also cover other usecases.
> > > 
> > > Since the available datasheet (https://www.ti.com/lit/gpn/DS125DF111)
> > > does not name the registers, the name for the macros were determined by
> > > their usage pattern.
> > > 
> > > A PHY device is created for each of the two channels present on the
> > > retimer. This allows for independent configuration of the two channels.
> > > This capability is especially important on retimers which have more than
> > > 2 channels that can be, depending on the board design, connected in
> > > multiple different ways to the SerDes lanes.
> > > 
> > > Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> > > ---
> > > Changes in v3:
> > > - Use reverse Christmas tree ordering
> > > - Print a symbolic description in case of error
> > > - Some words do not need to be capitalized
> > > - Remove duplicated exit code path
> > > - Return -EINVAL in case of unsupported submode received in .set_mode()
> > > - Add a .validate() callback
> > > - Remove comma after sentinel entry
> > > - Add a ds125df111_rmw() helper
> > > - Use read_poll_timeout() to wait for channel reset to complete
> > > 
> > > Changes in v2:
> > > - Explicitly include all the needed headers
> > > - Change ds125df111_xlate() so that it returns an error if args_count is
> > > not exactly 1
> > > - Add a MAINTAINERS entry
> > > ---
> > >  MAINTAINERS                     |   7 +
> > >  drivers/phy/ti/Kconfig          |  10 ++
> > >  drivers/phy/ti/Makefile         |   1 +
> > >  drivers/phy/ti/phy-ds125df111.c | 294 ++++++++++++++++++++++++++++++++
> > >  4 files changed, 312 insertions(+)
> > >  create mode 100644 drivers/phy/ti/phy-ds125df111.c
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index f877e5aaf2c7..58f410b666e7 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -26781,6 +26781,13 @@ T:	git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
> > >  F:	drivers/media/platform/ti/davinci/
> > >  F:	include/media/davinci/
> > >  
> > > +TI DS125DF111 RETIMER PHY DRIVER
> > > +M:	Ioana Ciornei <ioana.ciornei@nxp.com>
> > > +L:	linux-phy@lists.infradead.org (moderated for non-subscribers)
> > > +S:	Maintained
> > > +F:	Documentation/devicetree/bindings/phy/ti,ds125df111.yaml
> > > +F:	drivers/phy/ti/phy-ds125df111.c
> > > +
> > >  TI ENHANCED CAPTURE (eCAP) DRIVER
> > >  M:	Vignesh Raghavendra <vigneshr@ti.com>
> > >  R:	Julien Panis <jpanis@baylibre.com>
> > > diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
> > > index b40f28019131..475e80fcd52d 100644
> > > --- a/drivers/phy/ti/Kconfig
> > > +++ b/drivers/phy/ti/Kconfig
> > > @@ -111,3 +111,13 @@ config PHY_TI_GMII_SEL
> > >  	help
> > >  	  This driver supports configuring of the TI CPSW Port mode depending on
> > >  	  the Ethernet PHY connected to the CPSW Port.
> > > +
> > > +config PHY_TI_DS125DF111
> > 
> > This should be in alphabetical order, so I guess before PHY_TI_G...
> 
> Now that I actually tried to make the change that you requested, I
> realised that the Kconfig is not following any alphabetical order. And
> neither does the Makefile.
> 
> Do you still want me to move the entries?

Yes please. I will sort this one later in the cycle again!

-- 
~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 0/4] Extend phy_configure_opts_mipi_dphy to support position and polarity
From: Vinod Koul @ 2026-05-19 10:27 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Neil Armstrong, Marco Felsch, Maxime Ripard, linux-phy,
	linux-kernel
In-Reply-To: <20260325-dphy-params-extension-v1-0-c6df5599284a@linaro.org>

On 25-03-26, 21:47, Bryan O'Donoghue wrote:
> struct phy_configure_opts_mipi_dphy currently passes @lanes as a linear
> count of data-lanes starting from lane zero to a consuming DPHY driver.
> 
> This proves insufficient when we want to specify lane location and lane
> polarity.
> 
> To address this gap extend the structure to pass four new fields.

Sure, but where is the user...?
Please repost with users added in

Thanks

pw-bot: cr

-- 
~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH net-next v4] net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c
From: Maxime Chevallier @ 2026-05-19 10:13 UTC (permalink / raw)
  To: Petr Wozniak, netdev; +Cc: bjorn, andrew, linux-phy, kuba
In-Reply-To: <20260519043249.2868-1-petr.wozniak@gmail.com>

Hi Petr,

On 5/19/26 06:32, Petr Wozniak wrote:
> The "OEM"/"SFP-10G-T" quirk entry in sfp_fixup_rollball_cc()
> unconditionally forces MDIO_I2C_ROLLBALL for all modules matching that
> vendor/part-number combination.  This works for modules that genuinely
> implement a RollBall I2C-to-MDIO bridge, but silently breaks modules
> that share the same EEPROM strings without having such a bridge.
> 
> The Realtek RTL8261BE-CG is one such module: a pure copper 10G SFP+
> media converter with no I2C-to-MDIO bridge.  Its EEPROM reports
> vendor="OEM", part="SFP-10G-T-I", and -- critically -- Vendor OUI
> 00:00:00, making OUI-based differentiation impossible.  With
> MDIO_I2C_ROLLBALL the kernel stalls waiting for a PHY that never
> appears:
> 
>    sfp sfp2: probing phy device through the [MDIO_I2C_ROLLBALL] protocol

Is it really stalling, or are you facing the 25 seconds retry loop for 
rollball ?

> 
> Move the probe into i2c_mii_init_rollball() in mdio-i2c.c, where the
> RollBall protocol constants are already defined.  After sending the
> unlock password, issue a CMD_READ and wait ~70 ms for CMD_DONE.  A
> genuine RollBall bridge asserts CMD_DONE within that window; modules
> without a bridge never do, so i2c_mii_init_rollball() returns -ENODEV.
> mdio_i2c_alloc() propagates -ENODEV to the caller without logging an
> error.  sfp_sm_add_mdio_bus() catches -ENODEV and transitions
> sfp->mdio_protocol to MDIO_I2C_NONE so the rest of the state machine
> skips PHY probing for this module.
> 
> Add "OEM"/"SFP-10G-T-I" to the quirk table so RTL8261BE modules enter
> the probe path; genuine RollBall modules continue to work as before.
> 
> Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>

The overall approach is fine by me, I see that being potentially useful
for other use-cases (e.g. the 100FX modules that may or may not embed a
PHY).

we should document that a bit better though, stating that returning
-ENODEV from mdio_i2c_alloc() means we know for a fact there's no
PHY there.

I do have a few nitpicks, mostly style, see bellow, with these fixed you 
can add :

Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>

> ---
> 
> Changes since v3 (feedback from Jakub Kicinski):
>    - Drop spurious Tested-by: tag -- author and tester are the same person
>    - Use PATCH net-next subject prefix
>    - Move -ENODEV handling from sfp_i2c_mdiobus_create() into
>      sfp_sm_add_mdio_bus() so bus-creation code does not mutate
>      sfp->mdio_protocol; the state machine is the correct place for
>      protocol-state transitions
>    - Split combined variable declaration for clarity
> 
> Changes since v2:
>    - Compile-tested and hardware-tested on BPI-R4 (MT7988A, 6.12.87)
>    - RTL8261BE (OEM/SFP-10G-T-I): probes MDIO_I2C_NONE, link Up 10Gbps
>    - Genuine RollBall (OEM/SFP-10G-T): bridge detected, link Up 10Gbps
> 
>   drivers/net/mdio/mdio-i2c.c | 57 +++++++++++++++++++++++++++++++-----
>   drivers/net/phy/sfp.c       | 15 ++++++++--
>   2 files changed, 62 insertions(+), 10 deletions(-)
> 
> --- a/drivers/net/mdio/mdio-i2c.c
> +++ b/drivers/net/mdio/mdio-i2c.c
> @@ -419,6 +419,46 @@
>   	return 0;
>   }
>   
> +static int i2c_mii_probe_rollball(struct i2c_adapter *i2c)
> +{
> +	u8 data_buf[] = { ROLLBALL_DATA_ADDR, 0x01, 0x00, 0x00 };
> +	u8 cmd_buf[]  = { ROLLBALL_CMD_ADDR, ROLLBALL_CMD_READ };
> +	u8 cmd_addr = ROLLBALL_CMD_ADDR;
> +	u8 result;
> +	struct i2c_msg msgs[2];
> +	int ret;

You should follow reverse-xmas tree ordering, sorting by descending line
length.

> +
> +	msgs[0].addr  = ROLLBALL_PHY_I2C_ADDR;
> +	msgs[0].flags = 0;
> +	msgs[0].len   = sizeof(data_buf);
> +	msgs[0].buf   = data_buf;
> +	msgs[1].addr  = ROLLBALL_PHY_I2C_ADDR;
> +	msgs[1].flags = 0;
> +	msgs[1].len   = sizeof(cmd_buf);
> +	msgs[1].buf   = cmd_buf;
> +
> +	ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
> +	if (ret)
> +		return ret;
> +
> +	msleep(70);
> +
> +	msgs[0].addr  = ROLLBALL_PHY_I2C_ADDR;
> +	msgs[0].flags = 0;
> +	msgs[0].len   = 1;
> +	msgs[0].buf   = &cmd_addr;
> +	msgs[1].addr  = ROLLBALL_PHY_I2C_ADDR;
> +	msgs[1].flags = I2C_M_RD;
> +	msgs[1].len   = 1;
> +	msgs[1].buf   = &result;
> +
> +	ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
> +	if (ret)
> +		return ret;
> +
> +	return result == ROLLBALL_CMD_DONE ? 0 : -ENODEV;
> +}
> +
>   static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
>   {
>   	struct i2c_msg msg;
> @@ -439,10 +479,10 @@
>   	ret = i2c_transfer(i2c, &msg, 1);
>   	if (ret < 0)
>   		return ret;
> -	else if (ret != 1)
> +	if (ret != 1)
>   		return -EIO;
> -	else
> -		return 0;
> +
> +	return i2c_mii_probe_rollball(i2c);
>   }
>   
>   static bool mdio_i2c_check_functionality(struct i2c_adapter *i2c,
> @@ -487,9 +527,10 @@
>   	case MDIO_I2C_ROLLBALL:
>   		ret = i2c_mii_init_rollball(i2c);
>   		if (ret < 0) {
> -			dev_err(parent,
> -				"Cannot initialize RollBall MDIO I2C protocol: %d\n",
> -				ret);
> +			if (ret != -ENODEV)
> +				dev_err(parent,
> +					"Cannot initialize RollBall MDIO I2C protocol: %d\n",
> +					ret);
>   			mdiobus_free(mii);
>   			return ERR_PTR(ret);
>   		}
> --- a/drivers/net/phy/sfp.c
> +++ b/drivers/net/phy/sfp.c
> @@ -579,7 +579,8 @@
>   	// OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
>   	SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
>   
> -	SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
> +	SFP_QUIRK_F("OEM", "SFP-10G-T-I", sfp_fixup_rollball),
> +	SFP_QUIRK_F("OEM", "SFP-10G-T",   sfp_fixup_rollball_cc),

there's an extra space added for the "SFP-10G-T" entry, which makes it 
appear in the diff unnecessarily.

>   	SFP_QUIRK_S("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
>   	SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-D", sfp_quirk_2500basex),
>   	SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-U", sfp_quirk_2500basex),
> @@ -2022,10 +2023,17 @@
>   
>   static int sfp_sm_add_mdio_bus(struct sfp *sfp)
>   {
> -	if (sfp->mdio_protocol != MDIO_I2C_NONE)
> -		return sfp_i2c_mdiobus_create(sfp);
> +	int ret;
>   
> -	return 0;
> +	if (sfp->mdio_protocol == MDIO_I2C_NONE)
> +		return 0;
> +
> +	ret = sfp_i2c_mdiobus_create(sfp);
> +	if (ret == -ENODEV) {
> +		sfp->mdio_protocol = MDIO_I2C_NONE;
> +		return 0;
> +	}
> +	return ret;
>   }
>   
>   /* Probe a SFP for a PHY device if the module supports copper - the PHY

Maxime


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 2/4] arm64: dts: qcom: Introduce Shikra SoC base dtsi
From: Komal Bajaj @ 2026-05-19  9:49 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: linux-phy, krzk+dt, devicetree, neil.armstrong, olteanv, conor+dt,
	robh, vkoul
In-Reply-To: <20260513040623.03F36C2BCC7@smtp.kernel.org>

On 5/13/2026 9:36 AM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] Invalid PPI interrupt numbers (1, 2, 3, 0) are specified for the ARMv8 generic timer instead of the architecturally required numbers (13, 14, 11, 10).
> - [Medium] The `sdhc_1` node incorrectly uses RPMh interconnect tags (`QCOM_ICC_TAG_ALWAYS`, `QCOM_ICC_TAG_ACTIVE_ONLY`) on an RPM-based interconnect topology.
> - [Medium] The USB SuperSpeed wakeup interrupt (`ss_phy_irq`) directly references the GIC instead of routing through the MPM, breaking system wake-up from deep sleep.
> - [Low] The `sdhc_1` node uses the undeclared macro `RPMHPD_CX` for its `power-domains` property, which will cause a Device Tree compiler syntax error.
> --
>
> commit e2ee94ef3a5741f2cb9aae14dbef52c5f4a760f1
> Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
> Subject: arm64: dts: qcom: Introduce Shikra SoC base dtsi
>
> This commit adds initial device tree support for the Qualcomm Shikra SoC, an
> IoT-focused platform featuring a Cortex-A55 and Cortex-A78C cluster. It
> configures RPM-based power and clock management alongside various peripherals
> like USB, eMMC, and the generic timer.
>
>> diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
>> new file mode 100644
>> index 0000000000000..262c488add1ec
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
> [ ... ]
>
>> +		sdhc_1: mmc@4744000 {
>> +			compatible = "qcom,shikra-sdhci", "qcom,sdhci-msm-v5";
>> +
>> +			reg = <0x0 0x04744000 0x0 0x1000>,
>> +			      <0x0 0x04745000 0x0 0x1000>;
> [ ... ]
>
>> +			interconnects = <&system_noc MASTER_SDCC_1 QCOM_ICC_TAG_ALWAYS
>> +					&mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>,
>> +					<&mem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ACTIVE_ONLY
>> +					&config_noc SLAVE_SDCC_1 QCOM_ICC_TAG_ACTIVE_ONLY>;
> Since the Shikra SoC utilizes an RPM-based architecture, should this node use
> interconnect tags from qcom,rpm-icc.h (such as RPM_ALWAYS_TAG) instead?
> Passing RPMh interconnect tags from qcom,icc.h to an RPM interconnect provider
> might result in unhandled parameters or silent bandwidth request failures.

ACK, macro to be updated as per the RPM header. Will update in next series.

>
>> +			interconnect-names = "sdhc-ddr",
>> +					     "cpu-sdhc";
>> +
>> +			power-domains = <&rpmpd RPMHPD_CX>;
> Does this power-domains assignment use an undeclared macro? RPMHPD_CX belongs
> to RPMh-based power domains, while this platform relies on RPMPD. This looks
> like it will cause a dtc syntax error during the build.

ACK, PD to be updated as per the available and compatible power-domain 
as per the architecture.

>
> [ ... ]
>
>> +		usb_1: usb@4e00000 {
>> +			compatible = "qcom,shikra-dwc3", "qcom,snps-dwc3";
>> +			reg = <0x0 0x04e00000 0x0 0xfc100>;
> [ ... ]
>
>> +			interrupts-extended = <&intc GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
>> +					      <&intc GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
>> +					      <&intc GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
>> +					      <&intc GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
>> +					      <&intc GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-names = "dwc_usb3",
>> +					  "pwr_event",
>> +					  "qusb2_phy",
>> +					  "hs_phy_irq",
>> +					  "ss_phy_irq";
> The mpm node correctly maps pin 12 to GIC SPI 422 for the DWC3 ss_phy_irq.
> Could routing this directly to the GIC here instead of hierarchically through
> the mpm (e.g., <&mpm 12 IRQ_TYPE_LEVEL_HIGH>) prevent the hardware from
> waking up from low-power states upon USB activity?

ACK, will update to use MPM for ss_phy_irq instead of direct GIC for usb.

Thanks
Komal

>
> [ ... ]
>
>> +	timer {
>> +		compatible = "arm,armv8-timer";
>> +
>> +		interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_LOW>,
>> +			     <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW>,
>> +			     <GIC_PPI 3 IRQ_TYPE_LEVEL_LOW>,
>> +			     <GIC_PPI 0 IRQ_TYPE_LEVEL_LOW>;
>> +	};
> Are these PPI interrupt numbers correct for the ARMv8 generic timer? The
> architecturally defined numbers are typically 13 for Secure, 14 for Non-secure,
> 11 for Virtual, and 10 for Hypervisor. Using invalid hardware IRQ lines here
> could prevent the kernel from receiving scheduler ticks and stall the boot.
>
>> +};


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [RFC PATCH] phy: ti: tusb1210: Move long delayed work on system_dfl_long_wq
From: Marco Crivellari @ 2026-05-19  8:55 UTC (permalink / raw)
  To: linux-kernel, linux-phy
  Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
	Sebastian Andrzej Siewior, Michal Hocko, Vinod Koul,
	Neil Armstrong
In-Reply-To: <20260507131439.264906-1-marco.crivellari@suse.com>

On Thu, May 7, 2026 at 3:14 PM Marco Crivellari
<marco.crivellari@suse.com> wrote:
> [...]
>  drivers/phy/ti/phy-tusb1210.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Gentle ping.

Thanks!

-- 

Marco Crivellari

SUSE Labs

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH] MAINTAINERS: Hand over phy-zynqmp to Tomi Valkeinen
From: Pandey, Radhey Shyam @ 2026-05-19  8:48 UTC (permalink / raw)
  To: Laurent Pinchart, linux-phy, linux-kernel
  Cc: Tomi Valkeinen, vkoul, neil.armstrong, michal.simek,
	Radhey Shyam Pandey
In-Reply-To: <20260519082253.40142-1-laurent.pinchart@ideasonboard.com>

On 5/19/2026 1:52 PM, Laurent Pinchart wrote:
> I volunteered to maintain the phy-zynqmp driver as part of my work on
> the ZynqMP DPSUB driver. Now that Tomi has taken over the DPSUB, it
> makes sense for him to handle the phy-zynqmp driver as well.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Acked-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Thanks!

> ---
> I would also be happy if someone from AMD would like to take over
> maitainership of the driver.
> ---
>   MAINTAINERS | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 63389fea5d15..458f2b77d4ce 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -29293,7 +29293,7 @@ F:	Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yam
>   F:	drivers/edac/zynqmp_edac.c
>   
>   XILINX ZYNQMP PSGTR PHY DRIVER
> -M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> +M:	Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>   L:	linux-kernel@vger.kernel.org
>   S:	Supported
>   T:	git https://github.com/Xilinx/linux-xlnx.git


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 0/3] phy: zynqmp: fix SERDES scrambler register handling and enable for USB
From: Pandey, Radhey Shyam @ 2026-05-19  8:45 UTC (permalink / raw)
  To: Laurent Pinchart, Radhey Shyam Pandey
  Cc: vkoul, neil.armstrong, michal.simek, linux-kernel, linux-phy,
	linux-arm-kernel, git, Tomi Valkeinen
In-Reply-To: <20260519082526.GB16205@killaraus.ideasonboard.com>

On 5/19/2026 1:55 PM, Laurent Pinchart wrote:
> Hi Radhey,
> 
> I haven't really been involved with the phy-zynqmp driver for a while,
> despite still being listed as a maintainer. I have just sent a patch
> (you're on CC) to hand maintainership duties over to Tomi Valkeinen, who
> took over maintainership of the ZynqMP DPSUB driver. As Tomi isn't
> really involved with the PHYs, in particular with the non-DP PHYs
> supported by the driver, it could also make more sense for someone from
> AMD to take over maintainer duties for phy-zynqmp.

Thanks for your continued support. As i am handling this driver
internally will send out a patch to also add myself as maintainer.

Thanks,
Radhey>
> On Mon, May 11, 2026 at 10:01:32PM +0530, Radhey Shyam Pandey wrote:
>> This series fixes three related issues in the ZynqMP SERDES PHY
>> scrambler/encoder bypass path:
>>
>> 1. The L0_TM_DISABLE_SCRAMBLE_ENCODER mask incorrectly included bit 2
>>     of L0_TX_DIG_61, which is a reserved read-only field. Correct the
>>     mask to (BIT(3) | GENMASK(1, 0)).
>>
>> 2. xpsgtr_bypass_scrambler_8b10b() used xpsgtr_write_phy() which
>>     performs a full register write, clobbering unrelated bits. Switch
>>     to xpsgtr_clr_set_phy() with clr=mask, set=mask to preserve other
>>     register fields.
>>
>> 3. USB Gen1 requires PHY-side scrambling and 8b/10b encoding as
>>     mandated by the USB 3.x specification. The driver was incorrectly
>>     bypassing these for USB, the same as SATA and SGMII where encoding
>>     is handled in the controller.
>>
>> Nava kishore Manne (3):
>>    phy: zynqmp: fix L0_TM_DISABLE_SCRAMBLE_ENCODER mask
>>    phy: zynqmp: use read-modify-write for SERDES scrambler bypass
>>    phy: zynqmp: keep SERDES scrambler and 8b/10b enabled for USB
>>
>>   drivers/phy/xilinx/phy-zynqmp.c | 37 ++++++++++++++++++++++++++-------
>>   1 file changed, 30 insertions(+), 7 deletions(-)
>>
>>
>> base-commit: 5d6919055dec134de3c40167a490f33c74c12581
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH] MAINTAINERS: Hand over phy-zynqmp to Tomi Valkeinen
From: Tomi Valkeinen @ 2026-05-19  8:25 UTC (permalink / raw)
  To: Laurent Pinchart, linux-phy, linux-kernel
  Cc: vkoul, neil.armstrong, michal.simek, Radhey Shyam Pandey
In-Reply-To: <20260519082253.40142-1-laurent.pinchart@ideasonboard.com>


On 5/19/26 10:22, Laurent Pinchart wrote:
> I volunteered to maintain the phy-zynqmp driver as part of my work on
> the ZynqMP DPSUB driver. Now that Tomi has taken over the DPSUB, it
> makes sense for him to handle the phy-zynqmp driver as well.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> I would also be happy if someone from AMD would like to take over
> maitainership of the driver.
> ---
>   MAINTAINERS | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 63389fea5d15..458f2b77d4ce 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -29293,7 +29293,7 @@ F:	Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yam
>   F:	drivers/edac/zynqmp_edac.c
>   
>   XILINX ZYNQMP PSGTR PHY DRIVER
> -M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> +M:	Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>   L:	linux-kernel@vger.kernel.org
>   S:	Supported
>   T:	git https://github.com/Xilinx/linux-xlnx.git

Acked-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

  Tomi


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 0/3] phy: zynqmp: fix SERDES scrambler register handling and enable for USB
From: Laurent Pinchart @ 2026-05-19  8:25 UTC (permalink / raw)
  To: Radhey Shyam Pandey
  Cc: vkoul, neil.armstrong, michal.simek, linux-kernel, linux-phy,
	linux-arm-kernel, git, Tomi Valkeinen
In-Reply-To: <20260511163135.2924642-1-radhey.shyam.pandey@amd.com>

Hi Radhey,

I haven't really been involved with the phy-zynqmp driver for a while,
despite still being listed as a maintainer. I have just sent a patch
(you're on CC) to hand maintainership duties over to Tomi Valkeinen, who
took over maintainership of the ZynqMP DPSUB driver. As Tomi isn't
really involved with the PHYs, in particular with the non-DP PHYs
supported by the driver, it could also make more sense for someone from
AMD to take over maintainer duties for phy-zynqmp.

On Mon, May 11, 2026 at 10:01:32PM +0530, Radhey Shyam Pandey wrote:
> This series fixes three related issues in the ZynqMP SERDES PHY
> scrambler/encoder bypass path:
> 
> 1. The L0_TM_DISABLE_SCRAMBLE_ENCODER mask incorrectly included bit 2
>    of L0_TX_DIG_61, which is a reserved read-only field. Correct the
>    mask to (BIT(3) | GENMASK(1, 0)).
> 
> 2. xpsgtr_bypass_scrambler_8b10b() used xpsgtr_write_phy() which
>    performs a full register write, clobbering unrelated bits. Switch
>    to xpsgtr_clr_set_phy() with clr=mask, set=mask to preserve other
>    register fields.
> 
> 3. USB Gen1 requires PHY-side scrambling and 8b/10b encoding as
>    mandated by the USB 3.x specification. The driver was incorrectly
>    bypassing these for USB, the same as SATA and SGMII where encoding
>    is handled in the controller.
> 
> Nava kishore Manne (3):
>   phy: zynqmp: fix L0_TM_DISABLE_SCRAMBLE_ENCODER mask
>   phy: zynqmp: use read-modify-write for SERDES scrambler bypass
>   phy: zynqmp: keep SERDES scrambler and 8b/10b enabled for USB
> 
>  drivers/phy/xilinx/phy-zynqmp.c | 37 ++++++++++++++++++++++++++-------
>  1 file changed, 30 insertions(+), 7 deletions(-)
> 
> 
> base-commit: 5d6919055dec134de3c40167a490f33c74c12581

-- 
Regards,

Laurent Pinchart

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH] MAINTAINERS: Hand over phy-zynqmp to Tomi Valkeinen
From: Laurent Pinchart @ 2026-05-19  8:22 UTC (permalink / raw)
  To: linux-phy, linux-kernel
  Cc: Tomi Valkeinen, vkoul, neil.armstrong, michal.simek,
	Radhey Shyam Pandey

I volunteered to maintain the phy-zynqmp driver as part of my work on
the ZynqMP DPSUB driver. Now that Tomi has taken over the DPSUB, it
makes sense for him to handle the phy-zynqmp driver as well.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
I would also be happy if someone from AMD would like to take over
maitainership of the driver.
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 63389fea5d15..458f2b77d4ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29293,7 +29293,7 @@ F:	Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yam
 F:	drivers/edac/zynqmp_edac.c
 
 XILINX ZYNQMP PSGTR PHY DRIVER
-M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+M:	Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
 L:	linux-kernel@vger.kernel.org
 S:	Supported
 T:	git https://github.com/Xilinx/linux-xlnx.git
-- 
Regards,

Laurent Pinchart


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: [PATCH 3/5] phy: qualcomm: qmp-combo: Add preliminary USB4 support
From: Konrad Dybcio @ 2026-05-19  8:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Konrad Dybcio, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, linux-kernel,
	linux-phy, linux-arm-msm, devicetree, usb4-upstream,
	Raghavendra Thoorpu, Mika Westerberg, Sven Peter
In-Reply-To: <uc2l2mbobmik5workhcbtry5spe2gyamx2x4yj4rjly4t3dbrh@n34fo74rctnk>

On 5/18/26 5:38 PM, Dmitry Baryshkov wrote:
> On Mon, May 18, 2026 at 04:15:16PM +0200, Konrad Dybcio wrote:
>> On 5/18/26 3:57 PM, Dmitry Baryshkov wrote:
>>> On Mon, May 18, 2026 at 12:29:50PM +0200, Konrad Dybcio wrote:
>>>> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>>>
>>>> Some Combo PHYs (so far only on SC8280XP, X1E80100 and Glymur), come in
>>>> a flavor called USB43DP, which as the name implies, features USB4, USB3
>>>> and DP signal processing capabilities. In that architecture, USB3 and
>>>> USB4 PHYs share the same USB_PLL while featuring separate logic spaces.
>>>> The DP part is roughly the same as on the instances without USB4.
>>>>
>>>> The USB4 and USB3/DP operation modes of the PHY are mutually exclusive.
>>>> Only one USB protocol (and flavor of pipe clock) can be active at a
>>>> given moment (not to be confused with USB3 not being able to be
>>>> tunneled as USB4 packets - that of course remains possible).
>>>> The DP PLL is still used for clocking tunneled DP links. It may be
>>>> turned off to save power when no tunnels are active, but that's left as
>>>> a TODO item for now.
>>>>
>>>> Due to the nature of USB4, the Type-C handling happens entirely inside
>>>> the Host Router, and as such the QMPPHY's mux_set() function is
>>>> nullified for the period when USB4 PHY remains active. This is strictly
>>>> necessary, as the Host Router driver is going to excercise manual
>>>> control over the USB4 PHY's power state, which is needed by the suspend
>>>> and resume flows. Failure to control that synchronously with other
>>>> parts of the code results in a SoC crash by unlocked access.
>>>>
>>>> Because of that, a new struct phy is spawned to expose the USB4 mode,
>>>> along with a .set_mode callback to allow toggling between USB4 and TBT3
>>>> submodes.
>>>>
>>>> Thunderbolt 3, having a number of differences vs USB4, requires a
>>>> couple specific overrides, pertaining to electrical characteristics,
>>>> which are easily accommodated for.
>>>>
>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>>> ---
>>>>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 392 ++++++++++++++++++++++++------
>>>>  1 file changed, 322 insertions(+), 70 deletions(-)
>>>>
>>>
>>> Overall it looks good. The major question (after looking at TODOs), do
>>> we need a separate submode for USB+DP / TBT+DP?
>>
>> The problem space is as follows:
>>
>> After a TBT (collectively TBT3+ and USB4) link has been established and
>> we have a link partner, we may (based on the HW capabilities and user
>> config, such as kernel params but not only) start or stop a DP tunnel at
>> runtime. On Qualcomm hardware, the PHY is kept in USB4 mode and its DP
>> AUX lines are not used (instead, the encapsulated DP AUX packets are r/w
>> entirely within the USB4 subsystem via a pair of FIFOs that Linux sees
>> as a separate DP AUX host)
> 
> So far so good. But I still don't grok if having a DP-over-USB4 is a
> separate submode or not. I.e. I see code (and TODOs) to detect and
> handle DP going on and off. Would it be better if we specify that
> explicitly?

I really don't want to end up in a situation like we have with:

$ rg _USB include/linux/phy/phy.h
29:     PHY_MODE_USB_HOST,
30:     PHY_MODE_USB_HOST_LS,
31:     PHY_MODE_USB_HOST_FS,
32:     PHY_MODE_USB_HOST_HS,
33:     PHY_MODE_USB_HOST_SS,
34:     PHY_MODE_USB_DEVICE,
35:     PHY_MODE_USB_DEVICE_LS,
36:     PHY_MODE_USB_DEVICE_FS,
37:     PHY_MODE_USB_DEVICE_HS,
38:     PHY_MODE_USB_DEVICE_SS,
39:     PHY_MODE_USB_OTG,

>> Then, on hamoa/glymur specifically, any of the 3 USB4-capable DP hosts
>> can be muxed to either of the 2 DPIN ports on any of the 3 USB4 routers
>> (and each of these routers is hardwired to one of the PHYs).
>>
>> To underline, we have 3 DP producers and 6 consumers. If there's e.g. a
>> super high-res display at one of the physical ports, or a long
>> daisy-chain, we may need to use 2 DPTXes to service 1 receptacle. Then,
>> we would only need one of the PHYs (associated with the router that's
>> wired to that port) to provide a DP clock.
>>
>> This, along with the normal (logical or physical) present/absent status
>> can change at runtime. My plan is to use phy_set_opts(dp_tunelling=true)
>> or something along those lines to toggle that bit as necessary
> 
> I don't see phy_set_opts(). So maybe a submode then...

Sorry, I misremembered the name. The function is phy_configure(), and it
takes a union phy_configure_opts, hence the confusion

Konrad

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v1 5/6] dt-bindings: phy: tegra: Document Nvidia Tegra XMM6260 PHY
From: Svyatoslav Ryhel @ 2026-05-19  6:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Vinod Koul, Neil Armstrong, Thierry Reding, Jonathan Hunter,
	Greg Kroah-Hartman, Peter Chen, netdev, devicetree, linux-kernel,
	linux-phy, linux-tegra, linux-usb
In-Reply-To: <20260518-mustard-rabbit-of-ecstasy-eed3b6@quoll>

пн, 18 трав. 2026 р. о 15:14 Krzysztof Kozlowski <krzk@kernel.org> пише:
>
> On Fri, May 15, 2026 at 11:37:34AM +0300, Svyatoslav Ryhel wrote:
> > пт, 15 трав. 2026 р. о 11:20 Krzysztof Kozlowski <krzk@kernel.org> пише:
> > >
> > > On Mon, May 11, 2026 at 04:57:00PM +0300, Svyatoslav Ryhel wrote:
> > > > Document the XMM6260 PHY used by various devices based on the Nvidia Tegra
> > > > SoC, describing its usage
> > > >
> > > > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> > > > ---
> > > >  .../bindings/phy/nvidia,tegra-xmm6260.yaml    | 58 +++++++++++++++++++
> > > >  1 file changed, 58 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/phy/nvidia,tegra-xmm6260.yaml
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra-xmm6260.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra-xmm6260.yaml
> > > > new file mode 100644
> > > > index 000000000000..0346433c9772
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/phy/nvidia,tegra-xmm6260.yaml
> > > > @@ -0,0 +1,58 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/phy/nvidia,tegra-xmm6260.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Nvidia Tegra PHY for XMM6260 modem
> > >
> > > XMM6260 is Infineon modem, so any combination with nvidia,tegra is very
> > > confusing.
> > >
> >
> > May you please suggest how to adjust the name then? Thank you.
>
> Depending what is that. Start describing hardware, not driver behavior
> to help in that.
>
> >
> > > > +
> > > > +description:
> > > > +  A hardware configuration used in Tegra SoCs to provide proper interaction
> > > > +  between the application processor and the modem, as well as control over
> > > > +  one of the SoC's USB lines for the modem.
> > > > +
> > > > +maintainers:
> > > > +  - Svyatoslav Ryhel <clamor95@gmail.com>
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    const: nvidia,tegra-xmm6260
> > >
> > > Also here.
> > >
> > > What sort of phy is this? So far looks more like a software construct.
> > >
> >
> > Infineon XMM6260 does not work as an ordinary USB modem, it is a
> > standalone CPU which just exposes itself to AP via USB. In order to do
> > so, it has to have control over a USB bus of AP which is dedicated to
> > it. In case of Tegra - XMM6260 interaction it looks like this: second
> > Tegra USB controller is set into HSIC mode and is dedicated solely to
> > the modem, modem controls this USB bus. Then the main XMM6260 driver
> > performs power and init sequence and once it is ready it calls phy to
> > register controller. Phy has its own supply, controls USB controller
> > de/register and using enable GPIO sends signal to modem to proceed.
> > Additionally, since some XMM626 versions have a few steps to setup
> > exposing different USB devices, phy handles controller reinit for each
> > step. If treat XMM6260 as an simple USB modem it will never init.
> >
> > One more benefit of having PHY is that modem driver itself is generic
> > and PHY handles SoC specific configurations required by the modem.
> > Since this modem was used on a variety of different SoC's (Exynos and
> > OMAP for example) they can reuse modem's driver and provide only PHY
> > which handles modem interactions with the USB bus.
>
> Without any registers here, this is not a PHY but a power sequencing,
> just like we do for other USB or PCI devices.
>
> Optionally, it could be part of existing USB phy, when configuring it in
> HSIC mode, but it seems you add here supplies for the modem, not actual
> phy as the phy is undefined.
>
> The problem is that in the patch and explanation you mix driver model
> and driver behavior, so I really don't know what is this hardware. And
> it is not my job to guess, btw. A partial argument/proof why this is not
> a PHY, is that you reference the USB in the node, so phy-provider
> references the phy-consumer. That's reverse. If this is PHY, it's USB's
> HSIC phy, thus this needs to be referenced by USB.
>
> If this is power sequencing, then it can be represented as USB device,
> just like we do for all USB devices, but then it is not PHY and
> phy-cells are not appropriate.

I was looking into power sequencing and using it instead of phy is
perfectly fine for me. How I see XMM modem configuration:
- main device which handles most of generic power sequences,
init/deinit and detection for USB device (both, target USB device and
intermediate stages for fw loading)
- phy or power seq, does not matter, both fit, that performs
manipulations with SoC specific USB controller in order to ensure
correct modem boot

If I use power seq then modem will require link to power seq and power
seq will work with USB line, this should not create confusion of phy
acquiring USB that is phy consumer. Will this approach be acceptable?

>
>
> Best regards,
> Krzysztof
>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH V1 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Add Hawi UFS PHY compatible
From: Manivannan Sadhasivam @ 2026-05-19  6:05 UTC (permalink / raw)
  To: palash.kambar
  Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, alim.akhtar,
	avri.altman, bvanassche, andersson, dmitry.baryshkov, abel.vesa,
	luca.weiss, linux-arm-msm, linux-phy, devicetree, linux-kernel,
	linux-scsi
In-Reply-To: <20260518165346.1732548-2-palash.kambar@oss.qualcomm.com>

On Mon, May 18, 2026 at 10:23:44PM +0530, palash.kambar@oss.qualcomm.com wrote:
> From: Palash Kambar <palash.kambar@oss.qualcomm.com>
> 
> Document QMP UFS PHY compatible for Hawi SoC.
> 
> Signed-off-by: Palash Kambar <palash.kambar@oss.qualcomm.com>
> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml       | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> index 9616c736b6d4..2326dcf38a46 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> @@ -37,6 +37,7 @@ properties:
>                - qcom,kaanapali-qmp-ufs-phy
>            - const: qcom,sm8750-qmp-ufs-phy
>        - enum:
> +          - qcom,hawi-qmp-ufs-phy

Don't you need to add the Hawi compatible to the below check for clocks?

- Mani

-- 
மணிவண்ணன் சதாசிவம்

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH V1 2/3] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Document the Hawi UFS controller
From: Manivannan Sadhasivam @ 2026-05-19  5:54 UTC (permalink / raw)
  To: palash.kambar
  Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, alim.akhtar,
	avri.altman, bvanassche, andersson, dmitry.baryshkov, abel.vesa,
	luca.weiss, linux-arm-msm, linux-phy, devicetree, linux-kernel,
	linux-scsi
In-Reply-To: <20260518165346.1732548-3-palash.kambar@oss.qualcomm.com>

On Mon, May 18, 2026 at 10:23:45PM +0530, palash.kambar@oss.qualcomm.com wrote:
> From: Palash Kambar <palash.kambar@oss.qualcomm.com>
> 

Subject is wrong. It should be:

scsi: ufs: qcom: dt-bindings:

- Mani

> Document the UFS Controller on the Hawi Platform.
> 
> Signed-off-by: Palash Kambar <palash.kambar@oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
> index f28641c6e68f..3de00affa4c6 100644
> --- a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
> +++ b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
> @@ -16,6 +16,7 @@ select:
>        contains:
>          enum:
>            - qcom,eliza-ufshc
> +          - qcom,hawi-ufshc
>            - qcom,kaanapali-ufshc
>            - qcom,sm8650-ufshc
>            - qcom,sm8750-ufshc
> @@ -27,6 +28,7 @@ properties:
>      items:
>        - enum:
>            - qcom,eliza-ufshc
> +          - qcom,hawi-ufshc
>            - qcom,kaanapali-ufshc
>            - qcom,sm8650-ufshc
>            - qcom,sm8750-ufshc
> -- 
> 2.34.1
> 

-- 
மணிவண்ணன் சதாசிவம்

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH RFC v4 7/9] phy: qcom: qmp-pcie: Add link-mode multi-PHY probe infrastructure
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260518-link_mode_0519-v4-0-269cd73cc5d1@oss.qualcomm.com>

Some QMP PCIe PHY hardware blocks support multiple link topologies (e.g.
x8 or x4+x4) selected via a TCSR register. The existing probe path has
no way to model this: it assumes a single cfg per DT node and instantiates
exactly one PHY.

Introduce a link-mode probe path where match data carries a per-mode cfg
table. At probe time the driver reads the DT-selected mode, looks up the
corresponding cfg array, and instantiates only the sub-PHYs required by
that mode. A #phy-cells = <1> provider is registered so consumers can
address individual sub-PHYs by index.

Three new data structures support this: qmp_pcie_data holds per-provider
state including the phy array, active mode, and regmap for the mode
register; qmp_pcie_link_mode_cfg maps a mode index to its per-PHY cfg
array; qmp_pcie_match_data is the top-level match data for link-mode
platforms.

On the probe side, qmp_pcie_probe() is reworked to instantiate one
qmp_pcie per active sub-PHY and register the appropriate clock and phy
providers. Per-instance DT parsing and phy object creation are factored
into helpers to keep the probe path clean. The active link mode is written
to the TCSR register at power-on to handle re-initialisation after
low-power transitions.

Platforms without a "link-mode" property continue to use the existing
single-cfg path and of_phy_simple_xlate unchanged.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 351 +++++++++++++++++++++++++++----
 1 file changed, 311 insertions(+), 40 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index b100302be12a..d78d57fb64d6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/phy/pcie.h>
@@ -3342,6 +3343,28 @@ struct qmp_pcie {
 	struct clk_fixed_rate aux_clk_fixed;
 };
 
+struct qmp_pcie_data {
+	struct phy **phys;
+	u32 active_link_mode;
+	int num_phys;
+	struct regmap *link_mode_map;
+	u32 link_mode_offset;
+	struct mutex link_mode_lock;
+
+	int num_pipe_outputs;
+	struct clk_fixed_rate *pipe_out_clks;
+};
+
+struct qmp_pcie_link_mode_cfg {
+	const struct qmp_phy_cfg *cfgs[QMP_PHY_SELECTOR_1 + 1];
+	u32 num_phys;
+};
+
+struct qmp_pcie_match_data {
+	const struct qmp_pcie_link_mode_cfg *mode_cfgs;
+	u32 num_modes;
+};
+
 static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
 {
 	u32 reg;
@@ -4897,6 +4920,27 @@ static int qmp_pcie_exit(struct phy *phy)
 	return 0;
 }
 
+static int qmp_pcie_config_link_mode(struct qmp_pcie *qmp)
+{
+	struct qmp_pcie_data *qmp_data = dev_get_drvdata(qmp->dev);
+	int ret;
+
+	if (!qmp_data)
+		return 0;
+
+	mutex_lock(&qmp_data->link_mode_lock);
+
+	ret = regmap_write(qmp_data->link_mode_map, qmp_data->link_mode_offset,
+			   qmp_data->active_link_mode);
+	if (ret)
+		goto out_unlock;
+
+out_unlock:
+	mutex_unlock(&qmp_data->link_mode_lock);
+
+	return ret;
+}
+
 static int qmp_pcie_power_on(struct phy *phy)
 {
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
@@ -4907,6 +4951,10 @@ static int qmp_pcie_power_on(struct phy *phy)
 	unsigned int mask, val;
 	int ret;
 
+	ret = qmp_pcie_config_link_mode(qmp);
+	if (ret)
+		return ret;
+
 	/*
 	 * Write CSR register for PHY that doesn't support no_csr reset or has not
 	 * been initialized.
@@ -5229,6 +5277,20 @@ static struct clk_hw *qmp_pcie_clk_hw_get(struct of_phandle_args *clkspec, void
 	return ERR_PTR(-EINVAL);
 }
 
+static struct clk_hw *qmp_pcie_clk_hw_get_link_mode(struct of_phandle_args *clkspec, void *data)
+{
+	struct qmp_pcie_data *qmp_data = data;
+	unsigned int idx = 0;
+
+	if (clkspec->args_count)
+		idx = clkspec->args[0];
+
+	if (idx < (unsigned int)qmp_data->num_pipe_outputs)
+		return &qmp_data->pipe_out_clks[idx].hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
 static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np)
 {
 	int ret;
@@ -5258,6 +5320,37 @@ static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np
 	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
 }
 
+static int qmp_pcie_register_clocks_link_mode(struct device *dev,
+					      struct device_node *np,
+					      struct qmp_pcie_data *qmp_data)
+{
+	int num_pipe_outputs;
+	int i;
+	int ret;
+
+	num_pipe_outputs = of_property_count_strings(np, "clock-output-names");
+	if (num_pipe_outputs < 0)
+		num_pipe_outputs = 1;
+
+	qmp_data->num_pipe_outputs = num_pipe_outputs;
+	qmp_data->pipe_out_clks = devm_kcalloc(dev, num_pipe_outputs,
+					       sizeof(*qmp_data->pipe_out_clks), GFP_KERNEL);
+	if (!qmp_data->pipe_out_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < num_pipe_outputs; i++) {
+		ret = __phy_pipe_clk_register(dev, np, i, &qmp_data->pipe_out_clks[i]);
+		if (ret)
+			return ret;
+	}
+
+	ret = of_clk_add_hw_provider(np, qmp_pcie_clk_hw_get_link_mode, qmp_data);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, phy_clk_release_provider, np);
+}
+
 static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np)
 {
 	struct platform_device *pdev = to_platform_device(qmp->dev);
@@ -5437,36 +5530,102 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 	return 0;
 }
 
-static int qmp_pcie_probe(struct platform_device *pdev)
+static int qmp_pcie_read_link_mode(struct device *dev, struct regmap **mode_map,
+				   u32 *mode_offset,
+				   u32 *active_link_mode,
+				   u32 *hw_link_mode)
 {
-	struct dev_pm_domain_list *pd_list;
-	struct device *dev = &pdev->dev;
-	struct phy_provider *phy_provider;
-	struct device_node *np;
-	struct qmp_pcie *qmp;
-	struct phy *phy;
+	struct regmap *map;
+	unsigned int args[2];
+	unsigned int mode;
 	int ret;
 
-	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
-	if (!qmp)
+	map = syscon_regmap_lookup_by_phandle_args(dev->of_node, "qcom,link-mode",
+						   ARRAY_SIZE(args), args);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+
+	ret = regmap_read(map, args[0], &mode);
+	if (ret)
+		return ret;
+
+	*mode_map = map;
+	*mode_offset = args[0];
+	*active_link_mode = args[1];
+	*hw_link_mode = mode;
+
+	return 0;
+}
+
+static int qmp_pcie_validate_link_mode(struct device *dev,
+				       const struct qmp_pcie_link_mode_cfg *mode_cfg,
+				       u32 active_link_mode, u32 hw_link_mode)
+{
+	int i;
+
+	if (active_link_mode == hw_link_mode)
+		return 0;
+
+	for (i = 0; i < mode_cfg->num_phys; i++) {
+		const struct qmp_phy_cfg *cfg = mode_cfg->cfgs[i];
+
+		if (!cfg || !cfg->tbls.serdes_num) {
+			dev_err(dev,
+				"missing phy settings for link-mode %u, logical-phy %d (hw=%u)\n",
+				active_link_mode, i, hw_link_mode);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int qmp_pcie_parse_dt_non_primary(struct qmp_pcie *qmp)
+{
+	struct platform_device *pdev = to_platform_device(qmp->dev);
+	struct device *dev = qmp->dev;
+	char *pipe_clk_name;
+	char *pipediv2_clk_name;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, qmp->id);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	pipe_clk_name = devm_kasprintf(dev, GFP_KERNEL, "pipe_%c", 'a' + qmp->id);
+	pipediv2_clk_name = devm_kasprintf(dev, GFP_KERNEL, "pipediv2_%c", 'a' + qmp->id);
+	if (!pipe_clk_name || !pipediv2_clk_name)
 		return -ENOMEM;
 
-	qmp->dev = dev;
+	return qmp_pcie_parse_dt_common(qmp, base, pipe_clk_name, pipediv2_clk_name);
+}
+
+static int qmp_pcie_probe_phy(struct qmp_pcie *qmp, struct device_node *np,
+			      struct phy **out_phy)
+{
+	struct device *dev = qmp->dev;
+	struct device_node *phy_np;
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	int ret;
 
-	qmp->cfg = of_device_get_match_data(dev);
-	if (!qmp->cfg)
+	if (!cfg)
 		return -EINVAL;
 
-	WARN_ON_ONCE(!qmp->cfg->pwrdn_ctrl);
-	WARN_ON_ONCE(!qmp->cfg->phy_status);
+	WARN_ON_ONCE(!cfg->pwrdn_ctrl);
+	WARN_ON_ONCE(!cfg->phy_status);
 
-	ret = devm_pm_domain_attach_list(dev, NULL, &pd_list);
-	if (ret < 0 && ret != -EEXIST) {
-		dev_err(dev, "Failed to attach power domain\n");
-		return ret;
-	}
+	qmp->mode = PHY_MODE_PCIE_RC;
 
-	ret = devm_pm_runtime_enable(dev);
+	if (qmp->id == QMP_PHY_SELECTOR_0) {
+		phy_np = np;
+		if (np != dev->of_node)
+			ret = qmp_pcie_parse_dt_legacy(qmp, np);
+		else
+			ret = qmp_pcie_parse_dt(qmp);
+	} else {
+		phy_np = dev->of_node;
+		ret = qmp_pcie_parse_dt_non_primary(qmp);
+	}
 	if (ret)
 		return ret;
 
@@ -5482,35 +5641,147 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	/* Check for legacy binding with child node. */
-	np = of_get_next_available_child(dev->of_node, NULL);
-	if (np) {
-		ret = qmp_pcie_parse_dt_legacy(qmp, np);
-	} else {
-		np = of_node_get(dev->of_node);
-		ret = qmp_pcie_parse_dt(qmp);
+	*out_phy = devm_phy_create(dev, phy_np, &qmp_pcie_phy_ops);
+	if (IS_ERR(*out_phy)) {
+		ret = PTR_ERR(*out_phy);
+		return ret;
 	}
-	if (ret)
-		goto err_node_put;
 
-	ret = qmp_pcie_register_clocks(qmp, np);
+	phy_set_drvdata(*out_phy, qmp);
+
+	return 0;
+}
+
+static struct phy *qmp_pcie_link_mode_xlate(struct device *dev,
+					    const struct of_phandle_args *args)
+{
+	struct qmp_pcie_data *qmp_data = dev_get_drvdata(dev);
+	unsigned int idx;
+
+	if (!qmp_data)
+		return ERR_PTR(-EINVAL);
+
+	if (args->args_count < 1)
+		return ERR_PTR(-EINVAL);
+
+	idx = args->args[0];
+
+	if (idx < (unsigned int)qmp_data->num_phys)
+		return qmp_data->phys[idx] ?: ERR_PTR(-EINVAL);
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int qmp_pcie_probe(struct platform_device *pdev)
+{
+	struct dev_pm_domain_list *pd_list;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = NULL;
+	struct phy_provider *phy_provider;
+	const struct qmp_phy_cfg *cfg = NULL;
+	const struct qmp_pcie_match_data *mode_data;
+	const struct qmp_pcie_link_mode_cfg *mode_cfg;
+	const void *match_data;
+	struct qmp_pcie_data *qmp_data = NULL;
+	struct regmap *link_mode_map = NULL;
+	struct qmp_pcie *qmp;
+	struct phy **phys;
+	u32 link_mode_offset = 0;
+	u32 hw_link_mode = 0;
+	u32 link_mode = 0;
+	bool use_link_mode = false;
+	int i;
+	int num_phys = 1;
+	int ret;
+
+	ret = devm_pm_domain_attach_list(dev, NULL, &pd_list);
+	if (ret < 0 && ret != -EEXIST) {
+		dev_err(dev, "Failed to attach power domain\n");
+		return ret;
+	}
+
+	ret = devm_pm_runtime_enable(dev);
 	if (ret)
-		goto err_node_put;
+		return ret;
 
-	qmp->mode = PHY_MODE_PCIE_RC;
+	match_data = of_device_get_match_data(dev);
+	if (!match_data)
+		return -EINVAL;
+
+	ret = qmp_pcie_read_link_mode(dev, &link_mode_map, &link_mode_offset,
+				      &link_mode, &hw_link_mode);
+	if (ret == -ENOENT)
+		cfg = match_data;
+	else if (ret)
+		return dev_err_probe(dev, ret, "failed to read qcom,link-mode\n");
+
+	if (!ret) {
+		use_link_mode = true;
+		mode_data = match_data;
+		if (link_mode >= mode_data->num_modes) {
+			dev_err(dev, "invalid qcom,link-mode: %u\n", link_mode);
+			return -EINVAL;
+		}
 
-	phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
-	if (IS_ERR(phy)) {
-		ret = PTR_ERR(phy);
-		dev_err(dev, "failed to create PHY: %d\n", ret);
-		goto err_node_put;
+		mode_cfg = &mode_data->mode_cfgs[link_mode];
+		num_phys = mode_cfg->num_phys;
+
+		ret = qmp_pcie_validate_link_mode(dev, mode_cfg, link_mode, hw_link_mode);
+		if (ret)
+			return ret;
 	}
 
-	phy_set_drvdata(phy, qmp);
+	qmp = devm_kcalloc(dev, num_phys, sizeof(*qmp), GFP_KERNEL);
+	if (!qmp)
+		return -ENOMEM;
 
-	of_node_put(np);
+	phys = devm_kcalloc(dev, num_phys, sizeof(*phys), GFP_KERNEL);
+	if (!phys)
+		return -ENOMEM;
+
+	if (use_link_mode) {
+		qmp_data = devm_kzalloc(dev, sizeof(*qmp_data), GFP_KERNEL);
+		if (!qmp_data)
+			return -ENOMEM;
+		qmp_data->phys = phys;
+		qmp_data->active_link_mode = link_mode;
+		qmp_data->link_mode_map = link_mode_map;
+		qmp_data->link_mode_offset = link_mode_offset;
+		qmp_data->num_phys = num_phys;
+		mutex_init(&qmp_data->link_mode_lock);
+	}
+
+	np = of_get_next_available_child(dev->of_node, NULL);
+	if (!np)
+		np = of_node_get(dev->of_node);
+
+	for (i = 0; i < num_phys; i++) {
+		const struct qmp_phy_cfg *phy_cfg = use_link_mode ? mode_cfg->cfgs[i] : cfg;
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+		qmp[i].dev = dev;
+		qmp[i].id = i;
+		qmp[i].cfg = phy_cfg;
+		ret = qmp_pcie_probe_phy(&qmp[i], np, &phys[i]);
+		if (ret)
+			goto err_node_put;
+	}
+
+	if (use_link_mode) {
+		ret = qmp_pcie_register_clocks_link_mode(dev, np, qmp_data);
+		if (ret)
+			goto err_node_put;
+
+		dev_set_drvdata(dev, qmp_data);
+		phy_provider = devm_of_phy_provider_register(dev, qmp_pcie_link_mode_xlate);
+	} else {
+		ret = qmp_pcie_register_clocks(qmp, np);
+		if (ret)
+			goto err_node_put;
+
+		phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	}
+
+	of_node_put(np);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 

-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH RFC v4 9/9] arm64: dts: qcom: glymur: Wire PCIe3a/3b to shared Gen5x8 PHY
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260518-link_mode_0519-v4-0-269cd73cc5d1@oss.qualcomm.com>

Glymur PCIe3 uses a single shared Gen5x8 QMP PHY block. Model PCIe3a and
PCIe3b as consumers of that shared PHY provider instead of separate PHY
nodes.

Update the DTS wiring to:
- point GCC PCIe3A/3B pipe parents to the shared PHY clock outputs
- add PCIe3a controller node and route PCIe3a/PCIe3b port phys to
  &pcie3_phy using two-cell PHY arguments
- configure the shared PHY node with link-mode and dual pipe outputs

Use QMP_PCIE_GLYMUR_MODE_* dt-binding macros for mode selection.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/glymur-crd.dtsi |   5 +
 arch/arm64/boot/dts/qcom/glymur.dtsi     | 333 ++++++++++++++++++++++++++++++-
 2 files changed, 336 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
index 6e2e06ae6c8a..72a86881d36c 100644
--- a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
@@ -451,6 +451,11 @@ &pcie3b {
 	pinctrl-names = "default";
 };
 
+&pcie3_phy {
+	vdda-phy-supply = <&vreg_l3c_e1_0p89>;
+	vdda-pll-supply = <&vreg_l2c_e1_1p14>;
+};
+
 &pcie3b_port0 {
 	reset-gpios = <&tlmm 155 GPIO_ACTIVE_LOW>;
 	wake-gpios = <&tlmm 157 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index 9ea297588d07..87530c233050 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -757,8 +757,8 @@ gcc: clock-controller@100000 {
 				 <0>,				/* USB 2 Phy PCIE PIPEGMUX */
 				 <0>,				/* USB 2 Phy PIPEGMUX */
 				 <0>,				/* USB 2 Phy SYS PCIE PIPEGMUX */
-				 <0>,				/* PCIe 3a */
-				 <0>,				/* PCIe 3b */
+				 <&pcie3_phy 0>,		/* PCIe 3a pipe */
+				 <&pcie3_phy 1>,		/* PCIe 3b pipe */
 				 <&pcie4_phy>,			/* PCIe 4 */
 				 <&pcie5_phy>,			/* PCIe 5 */
 				 <&pcie6_phy>,			/* PCIe 6 */
@@ -2285,6 +2285,59 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
 			};
 		};
 
+		pcie3_phy: phy@f00000 {
+			compatible = "qcom,glymur-qmp-gen5x8-pcie-phy";
+			reg = <0x0 0x00f00000 0x0 0x10000>,
+			      <0x0 0x00f10000 0x0 0x10000>;
+
+			clocks = <&gcc GCC_PCIE_PHY_3A_AUX_CLK>,
+				 <&gcc GCC_PCIE_3A_CFG_AHB_CLK>,
+				 <&tcsr TCSR_PCIE_3_CLKREF_EN>,
+				 <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3A_PIPE_CLK>,
+				 <&gcc GCC_PCIE_PHY_3B_AUX_CLK>,
+				 <&gcc GCC_PCIE_3B_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3B_PIPE_CLK>,
+				 <&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "phy_b_aux",
+				      "cfg_ahb_b",
+				      "rchng_b",
+				      "pipe_b",
+				      "pipediv2_b";
+
+			resets = <&gcc GCC_PCIE_3A_PHY_BCR>,
+				 <&gcc GCC_PCIE_3A_NOCSR_COM_PHY_BCR>,
+				 <&gcc GCC_PCIE_3B_PHY_BCR>,
+				 <&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>;
+			reset-names = "phy",
+				      "phy_nocsr",
+				      "phy_b",
+				      "phy_b_nocsr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>,
+					  <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>, <100000000>;
+
+			power-domains = <&gcc GCC_PCIE_3A_PHY_GDSC>,
+					<&gcc GCC_PCIE_3B_PHY_GDSC>;
+
+			qcom,link-mode = <&tcsr 0x5000 QMP_PCIE_GLYMUR_MODE_X4X4>;
+
+			#clock-cells = <1>;
+			clock-output-names = "pcie3a_pipe_clk",
+					     "pcie3b_pipe_clk";
+
+			#phy-cells = <1>;
+
+			status = "disabled";
+		};
+
 		usb_hs_phy: phy@fa0000 {
 			compatible = "qcom,glymur-m31-eusb2-phy",
 				     "qcom,sm8750-m31-eusb2-phy";
@@ -3647,6 +3700,282 @@ pcie3b_port0: pcie@0 {
 				reg = <0x0 0x0 0x0 0x0 0x0>;
 				bus-range = <0x01 0xff>;
 
+				phys = <&pcie3_phy 1>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+		};
+
+		pcie3a: pci@1c10000 {
+			device_type = "pci";
+			compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100";
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x70000000 0x0 0xf20>,
+			      <0x0 0x70000f40 0x0 0xa8>,
+			      <0x0 0x70001000 0x0 0x4000>,
+			      <0x0 0x70100000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x70000000 0x0 0x70300000 0x0 0x3d00000>,
+				 <0x03000000 0x7 0x00000000 0x7 0x00000000 0x0 0x40000000>,
+				 <0x43000000 0x70 0x00000000 0x70 0x00000000 0x10 0x00000000>;
+
+			bus-range = <0 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <3>;
+			num-lanes = <8>;
+
+			operating-points-v2 = <&pcie3a_opp_table>;
+
+			msi-map = <0x0 &gic_its 0xb0000 0x10000>;
+			iommu-map = <0x0 &pcie_smmu 0x30000 0x10000>;
+
+			interrupts = <GIC_SPI 948 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 949 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 845 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 847 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 942 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7",
+					  "global";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 0 0 848 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 849 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 850 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 851 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_3A_AUX_CLK>,
+				 <&gcc GCC_PCIE_3A_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3A_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_3A_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_3A_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_3A_WEST_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "noc_aggr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3A_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_west_anoc MASTER_PCIE_3A QCOM_ICC_TAG_ALWAYS
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					&pcie_west_slv_noc SLAVE_PCIE_3A QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			resets = <&gcc GCC_PCIE_3A_BCR>,
+				 <&gcc GCC_PCIE_3A_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_3A_GDSC>;
+
+			eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555
+						     0x5555 0x5555 0x5555 0x5555>;
+			eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+			eq-presets-32gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+
+			status = "disabled";
+
+			pcie3a_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* GEN 1 x1 */
+				opp-2500000-1 {
+					opp-hz = /bits/ 64 <2500000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <250000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 1 x2 */
+				opp-5000000-1 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 1 x4 */
+				opp-10000000-1 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 1 x8 */
+				opp-20000000-1 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+					opp-level = <1>;
+				};
+
+				/* GEN 2 x1 */
+				opp-5000000-2 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 2 x2 */
+				opp-10000000-2 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 2 x4 */
+				opp-20000000-2 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 2 x8 */
+				opp-40000000-2 {
+					opp-hz = /bits/ 64 <40000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <4000000 1>;
+					opp-level = <2>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000-3 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <984500 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 3 x2 */
+				opp-16000000-3 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1969000 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 3 x4 */
+				opp-32000000-3 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <3938000 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 3 x8 */
+				opp-64000000-3 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <7876000 1>;
+					opp-level = <3>;
+				};
+
+				/* GEN 4 x1 */
+				opp-16000000-4 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <1969000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 4 x2 */
+				opp-32000000-4 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <3938000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 4 x4 */
+				opp-64000000-4 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <7876000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 4 x8 */
+				opp-128000000-4 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <15753000 1>;
+					opp-level = <4>;
+				};
+
+				/* GEN 5 x1 */
+				opp-32000000-5 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <3938000 1>;
+					opp-level = <5>;
+				};
+
+				/* GEN 5 x2 */
+				opp-64000000-5 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <7876000 1>;
+					opp-level = <5>;
+				};
+
+				/* GEN 5 x4 */
+				opp-128000000-5 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <15753000 1>;
+					opp-level = <5>;
+				};
+
+				/* GEN 5 x8 */
+				opp-256000000-5 {
+					opp-hz = /bits/ 64 <256000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <31506000 1>;
+					opp-level = <5>;
+				};
+			};
+
+			pcie3a_port0: pcie@0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				phys = <&pcie3_phy 0>;
+
 				#address-cells = <3>;
 				#size-cells = <2>;
 				ranges;

-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH RFC v4 8/9] phy: qcom: qmp-pcie: Add Glymur Gen5x8 PHY config and match data
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260518-link_mode_0519-v4-0-269cd73cc5d1@oss.qualcomm.com>

On Glymur, PCIe3 uses a single Gen5x8 QMP PHY hardware block that can
operate in two link topologies: x8 as one 8-lane PHY, or x4+x4 as two
independent 4-lane PHYs. Both topologies are served by the same DT node
since they share the same hardware block and TCSR mode register.

Per-topology reset and clock lists are introduced alongside the PHY
configs to reflect the different resource ownership in each mode. The
per-mode PHY configurations and match data are then added to wire the
two topologies into the link-mode infrastructure introduced in the
previous patch.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 80 +++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index d78d57fb64d6..d4aeb3e00955 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3399,7 +3399,7 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 
 /* list of clocks required by phy */
 static const char * const qmp_pciephy_clk_l[] = {
-	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux",
+	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux", "phy_b_aux",
 };
 
 static const char * const qmp_pciephy_secondary_clk_l[] = {
@@ -4746,6 +4746,81 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
 	.phy_status		= PHYSTATUS_4_20,
 };
 
+static const char * const qmp_pciephy_secondary_reset_l[] = {
+	"phy_b",
+};
+
+static const char * const qmp_pciephy_secondary_nocsr_reset_l[] = {
+	"phy_b_nocsr",
+};
+
+static const char * const glymur_pciephy_reset_l[] = {
+	"phy", "phy_b"
+};
+
+static const char * const glymur_pciephy_nocsr_reset_l[] = {
+	"phy_nocsr", "phy_b_nocsr",
+};
+
+static const struct qmp_phy_cfg glymur_qmp_gen5x4_secondary_pciephy_cfg = {
+	.lanes			= 4,
+
+	.offsets		= &qmp_pcie_offsets_v8_50,
+
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.reset_list		= qmp_pciephy_secondary_reset_l,
+	.num_resets		= ARRAY_SIZE(qmp_pciephy_secondary_reset_l),
+	.nocsr_reset_list	= qmp_pciephy_secondary_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(qmp_pciephy_secondary_nocsr_reset_l),
+
+	.regs			= pciephy_v8_50_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+};
+
+static const struct qmp_phy_cfg glymur_qmp_gen5x8_pciephy_cfg = {
+	.lanes = 8,
+
+	.offsets		= &qmp_pcie_offsets_v8_50,
+
+	.reset_list		= glymur_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(glymur_pciephy_reset_l),
+	.nocsr_reset_list	= glymur_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(glymur_pciephy_nocsr_reset_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+
+	.regs			= pciephy_v8_50_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+};
+
+static const struct qmp_pcie_link_mode_cfg glymur_qmp_gen5x8_mode_cfgs[] = {
+	[QMP_PCIE_GLYMUR_MODE_X8] = {
+		/* x8 */
+		.cfgs = {
+			[QMP_PHY_SELECTOR_0] = &glymur_qmp_gen5x8_pciephy_cfg,
+		},
+		.num_phys = 1,
+	},
+	[QMP_PCIE_GLYMUR_MODE_X4X4] = {
+		/* x4 + x4 */
+		.cfgs = {
+			[QMP_PHY_SELECTOR_0] = &glymur_qmp_gen5x4_pciephy_cfg,
+			[QMP_PHY_SELECTOR_1] = &glymur_qmp_gen5x4_secondary_pciephy_cfg,
+		},
+		.num_phys = 2,
+	},
+};
+
+static const struct qmp_pcie_match_data glymur_qmp_gen5x8_match_data = {
+	.mode_cfgs = glymur_qmp_gen5x8_mode_cfgs,
+	.num_modes = ARRAY_SIZE(glymur_qmp_gen5x8_mode_cfgs),
+};
+
 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -5797,6 +5872,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
 		.data = &glymur_qmp_gen5x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,glymur-qmp-gen5x8-pcie-phy",
+		.data = &glymur_qmp_gen5x8_match_data,
 	}, {
 		.compatible = "qcom,ipq6018-qmp-pcie-phy",
 		.data = &ipq6018_pciephy_cfg,

-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH RFC v4 4/9] phy: qcom: qmp-pcie: Support multiple nocsr resets
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260518-link_mode_0519-v4-0-269cd73cc5d1@oss.qualcomm.com>

Refactor nocsr reset handling to support multiple nocsr resets required
for PHY configurations with bifurcated operation modes.

The Glymur SoC's 3rd PCIe instance supports 8-lane mode using two PHYs
in bifurcation, where each PHY requires its own nocsr reset to be
controlled simultaneously. The current implementation only supports a
single nocsr reset per PHY configuration.

Add num_nocsr and nocsr_list fields to struct qmp_phy_cfg to represent the
number and names of a group of nocsr reset names. Initialize these fields
for all PHYs that have nocsr resets, allowing the driver to correctly
acquire multiple nocsr resets during probe and control them as an array
by using reset_control_bulk APIs.

The refactoring maintains backward compatibility for existing single
nocsr reset configurations while enabling support for multi-PHY
scenarios like Glymur's 8-lane bifurcation mode.

Additionally, introduces x1e80100_qmp_gen3x2_pciephy_cfg as a separate
configuration from sm8550_qmp_gen3x2_pciephy_cfg since the x1e80100 Gen3x2
PHY requires nocsr reset support while the sm8550 Gen3x2 PHY does not.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 87 ++++++++++++++++++++++++++++----
 1 file changed, 77 insertions(+), 10 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 832b5d93105b..1dee4733d4f2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3281,6 +3281,11 @@ struct qmp_phy_cfg {
 	/* resets to be requested */
 	const char * const *reset_list;
 	int num_resets;
+
+	/* nocsr resets to be requested */
+	const char * const *nocsr_reset_list;
+	int num_nocsr_resets;
+
 	/* regulators to be requested */
 	const char * const *vreg_list;
 	int num_vregs;
@@ -3327,7 +3332,7 @@ struct qmp_pcie {
 	int num_pipe_clks;
 
 	struct reset_control_bulk_data *resets;
-	struct reset_control *nocsr_reset;
+	struct reset_control_bulk_data *nocsr_reset;
 	struct regulator_bulk_data *vregs;
 
 	struct phy *phy;
@@ -3392,6 +3397,10 @@ static const char * const sdm845_pciephy_reset_l[] = {
 	"phy",
 };
 
+static const char * const sm8550_pciephy_nocsr_reset_l[] = {
+	"phy_nocsr",
+};
+
 static const struct qmp_pcie_offsets qmp_pcie_offsets_qhp = {
 	.serdes		= 0,
 	.pcs		= 0x1800,
@@ -4348,6 +4357,8 @@ static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {
 	},
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= sm8550_qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4380,6 +4391,8 @@ static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = {
 	},
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= sm8550_qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4480,6 +4493,35 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = {
 	.phy_status		= PHYSTATUS_4_20,
 };
 
+static const struct qmp_phy_cfg x1e80100_qmp_gen3x2_pciephy_cfg = {
+	.lanes = 2,
+
+	.offsets		= &qmp_pcie_offsets_v5,
+
+	.tbls = {
+		.serdes		= sm8550_qmp_gen3x2_pcie_serdes_tbl,
+		.serdes_num	= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_serdes_tbl),
+		.tx		= sm8550_qmp_gen3x2_pcie_tx_tbl,
+		.tx_num		= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_tx_tbl),
+		.rx		= sm8550_qmp_gen3x2_pcie_rx_tbl,
+		.rx_num		= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_rx_tbl),
+		.pcs		= sm8550_qmp_gen3x2_pcie_pcs_tbl,
+		.pcs_num	= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_tbl),
+		.pcs_misc	= sm8550_qmp_gen3x2_pcie_pcs_misc_tbl,
+		.pcs_misc_num	= ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_misc_tbl),
+	},
+	.reset_list		= sdm845_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= pciephy_v5_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS,
+};
+
 static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = {
 	.lanes = 2,
 
@@ -4502,6 +4544,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4535,6 +4579,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4566,6 +4612,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v6_regs_layout,
@@ -4581,6 +4629,8 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
 
 	.reset_list             = sdm845_pciephy_reset_l,
 	.num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list              = qmp_phy_vreg_l,
 	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs                   = pciephy_v6_regs_layout,
@@ -4609,6 +4659,8 @@ static const struct qmp_phy_cfg qmp_v8_gen3x2_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= pciephy_v8_regs_layout,
@@ -4624,6 +4676,8 @@ static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 
@@ -4640,6 +4694,8 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
 
 	.reset_list		= sdm845_pciephy_reset_l,
 	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.nocsr_reset_list	= sm8550_pciephy_nocsr_reset_l,
+	.num_nocsr_resets	= ARRAY_SIZE(sm8550_pciephy_nocsr_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 
@@ -4768,7 +4824,7 @@ static int qmp_pcie_init(struct phy *phy)
 		}
 	}
 
-	ret = reset_control_assert(qmp->nocsr_reset);
+	ret = reset_control_bulk_assert(cfg->num_nocsr_resets, qmp->nocsr_reset);
 	if (ret) {
 		dev_err(qmp->dev, "no-csr reset assert failed\n");
 		goto err_assert_reset;
@@ -4805,7 +4861,7 @@ static int qmp_pcie_exit(struct phy *phy)
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 
 	if (qmp->nocsr_reset)
-		reset_control_assert(qmp->nocsr_reset);
+		reset_control_bulk_assert(cfg->num_nocsr_resets, qmp->nocsr_reset);
 	else
 		reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 
@@ -4849,7 +4905,7 @@ static int qmp_pcie_power_on(struct phy *phy)
 	if (ret)
 		return ret;
 
-	ret = reset_control_deassert(qmp->nocsr_reset);
+	ret = reset_control_bulk_deassert(cfg->num_nocsr_resets, qmp->nocsr_reset);
 	if (ret) {
 		dev_err(qmp->dev, "no-csr reset deassert failed\n");
 		goto err_disable_pipe_clk;
@@ -4998,14 +5054,25 @@ static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
 	for (i = 0; i < cfg->num_resets; i++)
 		qmp->resets[i].id = cfg->reset_list[i];
 
-	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
+	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets,
+						    qmp->resets);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get resets\n");
 
-	qmp->nocsr_reset = devm_reset_control_get_optional_exclusive(dev, "phy_nocsr");
-	if (IS_ERR(qmp->nocsr_reset))
-		return dev_err_probe(dev, PTR_ERR(qmp->nocsr_reset),
-							"failed to get no-csr reset\n");
+	if (!cfg->num_nocsr_resets)
+		return 0;
+	qmp->nocsr_reset = devm_kcalloc(dev, cfg->num_nocsr_resets,
+				   sizeof(*qmp->nocsr_reset), GFP_KERNEL);
+	if (!qmp->nocsr_reset)
+		return -ENOMEM;
+
+	for (i = 0; i < cfg->num_nocsr_resets; i++)
+		qmp->nocsr_reset[i].id = cfg->nocsr_reset_list[i];
+
+	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_nocsr_resets,
+						    qmp->nocsr_reset);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get no-csr reset\n");
 
 	return 0;
 }
@@ -5520,7 +5587,7 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 		.data = &sm8750_qmp_gen3x2_pciephy_cfg,
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy",
-		.data = &sm8550_qmp_gen3x2_pciephy_cfg,
+		.data = &x1e80100_qmp_gen3x2_pciephy_cfg,
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy",
 		.data = &x1e80100_qmp_gen4x2_pciephy_cfg,

-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH RFC v4 6/9] phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector
From: Qiang Yu @ 2026-05-19  5:47 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Bjorn Andersson, Konrad Dybcio
  Cc: Qiang Yu, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260518-link_mode_0519-v4-0-269cd73cc5d1@oss.qualcomm.com>

PHY instances sharing a single DT node each need their own clocks and
resets. The current driver uses a single hardcoded clock list with no
way to select per-instance resources. Add the infrastructure needed
before wiring up multi-PHY probe.

qmp_pciephy_secondary_clk_l[] and qmp_pcie_get_clk_list(id) are added
to select the appropriate clock list by PHY selector index.
qmp_pcie_num_clks() replaces the hard-coded ARRAY_SIZE(qmp_pciephy_clk_l)
in qmp_pcie_init(), qmp_pcie_exit(), and qmp_pcie_clk_init().

struct qmp_pcie::phy is replaced with an id field so each instance can
identify its index within a multi-PHY provider.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 49 ++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 6332f15f78ca..b100302be12a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3335,7 +3335,7 @@ struct qmp_pcie {
 	struct reset_control_bulk_data *nocsr_reset;
 	struct regulator_bulk_data *vregs;
 
-	struct phy *phy;
+	u32 id;
 	int mode;
 
 	struct clk_fixed_rate pipe_clk_fixed;
@@ -3379,6 +3379,24 @@ static const char * const qmp_pciephy_clk_l[] = {
 	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux",
 };
 
+static const char * const qmp_pciephy_secondary_clk_l[] = {
+	"ref", "phy_b_aux", "cfg_ahb_b", "rchng_b",
+};
+
+static int qmp_pcie_get_clk_list(u32 id, const char * const **clk_list)
+{
+	switch (id) {
+	case QMP_PHY_SELECTOR_0:
+		*clk_list = qmp_pciephy_clk_l;
+		return ARRAY_SIZE(qmp_pciephy_clk_l);
+	case QMP_PHY_SELECTOR_1:
+		*clk_list = qmp_pciephy_secondary_clk_l;
+		return ARRAY_SIZE(qmp_pciephy_secondary_clk_l);
+	default:
+		return -EINVAL;
+	}
+}
+
 /* list of regulators */
 static const char * const qmp_phy_vreg_l[] = {
 	"vdda-phy", "vdda-pll",
@@ -4781,6 +4799,13 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
 	qmp_configure(qmp->dev, ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
 }
 
+static int qmp_pcie_num_clks(const struct qmp_pcie *qmp)
+{
+	const char * const *clk_list;
+
+	return qmp_pcie_get_clk_list(qmp->id, &clk_list);
+}
+
 static int qmp_pcie_init(struct phy *phy)
 {
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
@@ -4840,7 +4865,7 @@ static int qmp_pcie_init(struct phy *phy)
 		}
 	}
 
-	ret = clk_bulk_prepare_enable(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks);
+	ret = clk_bulk_prepare_enable(qmp_pcie_num_clks(qmp), qmp->clks);
 	if (ret)
 		goto err_assert_reset;
 
@@ -4865,7 +4890,7 @@ static int qmp_pcie_exit(struct phy *phy)
 	else
 		reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 
-	clk_bulk_disable_unprepare(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks);
+	clk_bulk_disable_unprepare(qmp_pcie_num_clks(qmp), qmp->clks);
 
 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 
@@ -5079,16 +5104,21 @@ static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
 
 static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
 {
+	const char * const *clk_list;
 	struct device *dev = qmp->dev;
-	int num = ARRAY_SIZE(qmp_pciephy_clk_l);
+	int num;
 	int i;
 
+	num = qmp_pcie_get_clk_list(qmp->id, &clk_list);
+	if (num < 0)
+		return num;
+
 	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
 	if (!qmp->clks)
 		return -ENOMEM;
 
 	for (i = 0; i < num; i++)
-		qmp->clks[i].id = qmp_pciephy_clk_l[i];
+		qmp->clks[i].id = clk_list[i];
 
 	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
 }
@@ -5414,6 +5444,7 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 	struct phy_provider *phy_provider;
 	struct device_node *np;
 	struct qmp_pcie *qmp;
+	struct phy *phy;
 	int ret;
 
 	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
@@ -5468,14 +5499,14 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 
 	qmp->mode = PHY_MODE_PCIE_RC;
 
-	qmp->phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
-	if (IS_ERR(qmp->phy)) {
-		ret = PTR_ERR(qmp->phy);
+	phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
+	if (IS_ERR(phy)) {
+		ret = PTR_ERR(phy);
 		dev_err(dev, "failed to create PHY: %d\n", ret);
 		goto err_node_put;
 	}
 
-	phy_set_drvdata(qmp->phy, qmp);
+	phy_set_drvdata(phy, qmp);
 
 	of_node_put(np);
 

-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox