Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2] phy: qcom: qmp-combo: Move pipe_clk on/off to common
From: Neil Armstrong @ 2026-03-02  9:45 UTC (permalink / raw)
  To: Val Packett, Konrad Dybcio, Vinod Koul, Kishon Vijay Abraham I,
	Bjorn Andersson, Wesley Cheng
  Cc: Dmitry Baryshkov, linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <20260228220634.22778-2-val@packett.cool>

On 2/28/26 23:05, 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.
> 
> Note: the suspend/resume callbacks were already gating the enable/disable
> of this clock only on init_count and not usb_init_count!
> 
> Signed-off-by: Val Packett <val@packett.cool>
> ---
> See https://lore.kernel.org/all/389ca5d3-a698-4dac-911c-39ba057e3d17@oss.qualcomm.com/ for more info.
> BTW https://lore.kernel.org/all/20260205160240.748371-2-loic.poulain@oss.qualcomm.com/ helped with coldplug.
> 
> v2: Reorder disables as suggested
> v1: https://lore.kernel.org/all/20250927093915.45124-2-val@packett.cool/
> ---
>   drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> index 93f1aa10d400..28428a8d1192 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> @@ -3691,6 +3691,13 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
>   	if (ret)
>   		goto err_assert_reset;
>   
> +	/* In DP-only mode, the pipe clk is still required for USB2 */
> +	ret = clk_prepare_enable(qmp->pipe_clk);
> +	if (ret) {
> +		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
> +		return ret;
> +	}
> +
>   	qphy_setbits(com, QPHY_V3_DP_COM_POWER_DOWN_CTRL, SW_PWRDN);
>   
>   	/* override hardware control for reset of qmp phy */
> @@ -3768,6 +3775,7 @@ static int qmp_combo_com_exit(struct qmp_combo *qmp, bool force)
>   
>   	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>   
> +	clk_disable_unprepare(qmp->pipe_clk);
>   	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>   
>   	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
> @@ -3871,12 +3879,6 @@ static int qmp_combo_usb_power_on(struct phy *phy)
>   
>   	qmp_configure(qmp->dev, serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
>   
> -	ret = clk_prepare_enable(qmp->pipe_clk);
> -	if (ret) {
> -		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
> -		return ret;
> -	}
> -
>   	/* Tx, Rx, and PCS configurations */
>   	qmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
>   	qmp_configure_lane(qmp->dev, tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
> @@ -3922,8 +3924,6 @@ static int qmp_combo_usb_power_off(struct phy *phy)
>   	struct qmp_combo *qmp = phy_get_drvdata(phy);
>   	const struct qmp_phy_cfg *cfg = qmp->cfg;
>   
> -	clk_disable_unprepare(qmp->pipe_clk);
> -
>   	/* PHY reset */
>   	qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>   

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

Thanks,
Neil

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

^ permalink raw reply

* Re: [PATCH v2 0/6] Fixes to Tegra USB role switching and phy handling
From: Vinod Koul @ 2026-03-02  9:59 UTC (permalink / raw)
  To: Diogo Ivo, Thierry Reding, Jonathan Hunter
  Cc: Mathias Nyman, Greg Kroah-Hartman, JC Kuo, Kishon Vijay Abraham I,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong,
	linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree,
	stable
In-Reply-To: <20260127-diogo-tegra_phy-v2-0-787b9eed3ed5@tecnico.ulisboa.pt>

On 27-01-26, 15:11, Diogo Ivo wrote:
> Hello,
> 
> This patch series contains fixes/improvements for USB role switching on the
> Tegra210 and Tegra186 SoCs.

Thierry, Jonathan

can you folks check this and r-b/t-b please

-- 
~Vinod

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

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add vdda-refgen supply for Glymur
From: Qiang Yu @ 2026-03-02 10:21 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Krzysztof Kozlowski, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, linux-phy,
	devicetree, linux-kernel
In-Reply-To: <hcslao22elcihjw56ltu4yo54lotheqpikzsrq6tia33di4fs4@2ygrbwhcfx2a>

On Fri, Feb 13, 2026 at 07:47:36PM +0200, Dmitry Baryshkov wrote:
> On Wed, Feb 11, 2026 at 07:32:23PM -0800, Qiang Yu wrote:
> > On Mon, Feb 09, 2026 at 09:06:23AM +0100, Krzysztof Kozlowski wrote:
> > > On Sun, Feb 08, 2026 at 08:49:39PM -0800, Qiang Yu wrote:
> > > > The PCIe QMP PHYs on Glymur require stable reference voltage provided by
> > > > refgen. The refgen itself requires two separate power supplies:
> > > > vdda-refgen0p9 and vdda-refgen1p2.
> > > > 
> > > > Since there is no dedicated driver for REFGEN, add vdda-refgen0p9-supply
> > > 
> > > How does the driver matter for the bindings? If I add dedicated driver
> > > for refgen, then I change the bindings?
> > 
> > Yeah, I know that dt-bindings should describe hardware, not software. But
> > what I meant to say is that the refgen is different from qref which is
> > controlled via TCSR registers and its LDOs are requested to vote in
> > tcsrcc driver. The refgen doesn't required register setting and it doesn't
> > have dedicated driver, so we vote its LDOs in phy driver. I will avoid
> > this statement in next version.
> 
> I must admit, I could not find references to the refgen in any of Glymur
> PCIe-related HPGs.
> 
> > 
> > > 
> > > There is qcom,sc8280xp-refgen-regulator so why there cannot be
> > > qcom,x1e-refgen-regulator?
> > 
> > I think we can and it seems better because the refgen for pcie phy also
> > supplies reference voltage to other modules like usb. But I checked the
> > qcom-refgen-regulator.c, it contains some register settings and there is
> > no LDOs voting. I'm not sure what does those register do, maybe Konrad
> > can provide some backgroud.
> 
> Those regs provide voting for refgen, because on those platforms DSI
> block doesn't have a hardware vote for refgen.

Hi Konrad, Dmitry

I tried to model the reference voltage as a fixed regulator but the fixed
regulator driver only supports a single vin-supply. However, the refgen
block requires two separate power supplies (1.2V and 0.9V LDOs).

Would it be appropriate to modify the qcom-refgen-regulator.c driver to
handle LDO voting for both the 1.2V and 0.9V supplies? In the regulator's
enable/disable callbacks, we could vote for and unvote these two LDOs
instead of performing register operations.

- Qiang Yu
> 
> > But on Glymur, we only need to vote LDOs. So
> > what if we use a fixed regulator in the device tree to represent refgen?
> > We could set refgen0p9 and refgen1p2 as its input supplies, then the PCIe
> > PHY would just need one refgen supply reference.
> > 
> > - Qiang Yu
> > > 
> > > 
> > > > and vdda-refgen1p2-supply properties to the PCIe PHY dt-bindings. Use
> > > > conditional schema to restrict these properties to only Glymur PCIe QMP
> > > > PHYs.
> > > 
> > > Best regards,
> > > Krzysztof
> > > 
> 
> -- 
> With best wishes
> Dmitry

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

^ permalink raw reply

* Re: [PATCH v2] phy: qcom: m31-eusb2: Make USB repeater optional
From: Konrad Dybcio @ 2026-03-02 10:43 UTC (permalink / raw)
  To: Abel Vesa, Vinod Koul, Neil Armstrong
  Cc: linux-arm-msm, linux-phy, linux-kernel, Wesley Cheng,
	Dmitry Baryshkov, Bjorn Andersson
In-Reply-To: <20260302-phy-qcom-m31-eusb2-make-repeater-optional-v2-1-dbf714c72056@oss.qualcomm.com>

On 3/2/26 9:34 AM, Abel Vesa wrote:
> From: Wesley Cheng <wesley.cheng@oss.qualcomm.com>
> 
> A repeater is not required for the PHY to function. On systems with
> multiple PHY instances connected to a multi-port controller, some PHYs
> may be unconnected. All PHYs must still probe successfully even without
> attached repeaters, otherwise the controller probe fails.
> 
> So make it optional.
> 
> Signed-off-by: Wesley Cheng <wesley.cheng@oss.qualcomm.com>
> [abel.vesa@oss.qualcomm.com: commit re-worded to reflect actual reason]
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Reviewed-by: Bjorn Andersson <andersson@kernel.org>
> Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add vdda-refgen supply for Glymur
From: Dmitry Baryshkov @ 2026-03-02 13:35 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Krzysztof Kozlowski, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, linux-phy,
	devicetree, linux-kernel
In-Reply-To: <aaVkpKZcrNM7k4Xm@hu-qianyu-lv.qualcomm.com>

On Mon, Mar 02, 2026 at 02:21:24AM -0800, Qiang Yu wrote:
> On Fri, Feb 13, 2026 at 07:47:36PM +0200, Dmitry Baryshkov wrote:
> > On Wed, Feb 11, 2026 at 07:32:23PM -0800, Qiang Yu wrote:
> > > On Mon, Feb 09, 2026 at 09:06:23AM +0100, Krzysztof Kozlowski wrote:
> > > > On Sun, Feb 08, 2026 at 08:49:39PM -0800, Qiang Yu wrote:
> > > > > The PCIe QMP PHYs on Glymur require stable reference voltage provided by
> > > > > refgen. The refgen itself requires two separate power supplies:
> > > > > vdda-refgen0p9 and vdda-refgen1p2.
> > > > > 
> > > > > Since there is no dedicated driver for REFGEN, add vdda-refgen0p9-supply
> > > > 
> > > > How does the driver matter for the bindings? If I add dedicated driver
> > > > for refgen, then I change the bindings?
> > > 
> > > Yeah, I know that dt-bindings should describe hardware, not software. But
> > > what I meant to say is that the refgen is different from qref which is
> > > controlled via TCSR registers and its LDOs are requested to vote in
> > > tcsrcc driver. The refgen doesn't required register setting and it doesn't
> > > have dedicated driver, so we vote its LDOs in phy driver. I will avoid
> > > this statement in next version.
> > 
> > I must admit, I could not find references to the refgen in any of Glymur
> > PCIe-related HPGs.
> > 
> > > 
> > > > 
> > > > There is qcom,sc8280xp-refgen-regulator so why there cannot be
> > > > qcom,x1e-refgen-regulator?
> > > 
> > > I think we can and it seems better because the refgen for pcie phy also
> > > supplies reference voltage to other modules like usb. But I checked the
> > > qcom-refgen-regulator.c, it contains some register settings and there is
> > > no LDOs voting. I'm not sure what does those register do, maybe Konrad
> > > can provide some backgroud.
> > 
> > Those regs provide voting for refgen, because on those platforms DSI
> > block doesn't have a hardware vote for refgen.
> 
> Hi Konrad, Dmitry
> 
> I tried to model the reference voltage as a fixed regulator but the fixed
> regulator driver only supports a single vin-supply. However, the refgen
> block requires two separate power supplies (1.2V and 0.9V LDOs).

On which platform? Does it require those power supplies only on GLymur
or on all relevant platforms?

> Would it be appropriate to modify the qcom-refgen-regulator.c driver to
> handle LDO voting for both the 1.2V and 0.9V supplies? In the regulator's
> enable/disable callbacks, we could vote for and unvote these two LDOs
> instead of performing register operations.

Depending on the answer on the previous question either we should fix
all refgens to use proper power supplies, or you should add separate,
Glymur-specific one (especially if you don't need to program it. Do
you?).

But, let's first sort out regulators for older platforms. Please inquiry
internally.

> > > But on Glymur, we only need to vote LDOs. So
> > > what if we use a fixed regulator in the device tree to represent refgen?
> > > We could set refgen0p9 and refgen1p2 as its input supplies, then the PCIe
> > > PHY would just need one refgen supply reference.
> > > 
> > > > > and vdda-refgen1p2-supply properties to the PCIe PHY dt-bindings. Use
> > > > > conditional schema to restrict these properties to only Glymur PCIe QMP
> > > > > PHYs.
> > > > 
> > > > Best regards,
> > > > Krzysztof
> > > > 
> > 
> > -- 
> > With best wishes
> > Dmitry

-- 
With best wishes
Dmitry

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

^ permalink raw reply

* Re: [PATCH v14 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
From: Luca Ceresoli @ 2026-03-02 17:49 UTC (permalink / raw)
  To: Chaoyi Chen, Heikki Krogerus, Greg Kroah-Hartman,
	Dmitry Baryshkov, Peter Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vinod Koul, Kishon Vijay Abraham I, Heiko Stuebner,
	Sandy Huang, Andy Yan, Yubing Zhang, Frank Wang, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
	Chaoyi Chen, Dragan Simic, Johan Jonker, Diederik de Haas,
	Peter Robinson
  Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
	linux-rockchip, dri-devel
In-Reply-To: <20260119073100.143-8-kernel@airkyi.com>

On Mon Jan 19, 2026 at 8:30 AM CET, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>
> The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
> the CDN-DP can be switched to output to one of the PHYs. If both ports
> are plugged into DP, DP will select the first port for output.
>
> This patch adds support for multiple bridges, enabling users to flexibly
> select the output port. For each PHY port, a separate encoder and bridge
> are registered.
>
> The change is based on the DRM AUX HPD bridge, rather than the
> extcon approach. This requires the DT to correctly describe the
> connections between the first bridge in bridge chain and DP
> controller. For example, the bridge chain may be like this:
>
> PHY aux birdge -> fsa4480 analog audio switch bridge ->
> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge
>
> In this case, the connection relationships among the PHY aux bridge
> and the DP contorller need to be described in DT.
>
> In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
> determines whether to register one or two bridges.
>
> Since there is only one DP controller, only one of the PHY ports can
> output at a time. The key is how to switch between different PHYs,
> which is handled by cdn_dp_switch_port() and cdn_dp_enable().
>
> There are two cases:
>
> 1. Neither bridge is enabled. In this case, both bridges can
> independently read the EDID, and the PHY port may switch before
> reading the EDID.
>
> 2. One bridge is already enabled. In this case, other bridges are not
> allowed to read the EDID. So we will try to return the cached EDID.
>
> Since the scenario of two ports plug in at the same time is rare,
> I don't have a board which support two TypeC connector to test this.
> Therefore, I tested forced switching on a single PHY port, as well as
> output using a fake PHY port alongside a real PHY port.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
>
> (no changes since v11)
>
> Changes in v10:
> - Fix refcount usage of drm_bridge.
> - Remove unused cdn_dp_next_bridge type.
>
> Changes in v9:
> - Select DRM_AUX_HPD_BRIDGE when using DP driver.
>
> (no changes since v7)
>
> Changes in v6:
> - Rename some variable names.
> - Attach the DP bridge to the next bridge.
>
> Changes in v5:
> - By parsing the HPD bridge chain, set the connector's of_node to the
> of_node corresponding to the USB-C connector.
> - Return EDID cache when other port is already enabled.
> ---
>
>  drivers/gpu/drm/rockchip/Kconfig       |   1 +
>  drivers/gpu/drm/rockchip/cdn-dp-core.c | 325 ++++++++++++++++++++-----
>  drivers/gpu/drm/rockchip/cdn-dp-core.h |  18 +-
>  3 files changed, 287 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
> index b7b025814e72..10d9f29a3d44 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP
>  	select DRM_DISPLAY_HELPER
>  	select DRM_BRIDGE_CONNECTOR
>  	select DRM_DISPLAY_DP_HELPER
> +	select DRM_AUX_HPD_BRIDGE
>  	help
>  	  This selects support for Rockchip SoC specific extensions
>  	  for the cdn DP driver. If you want to enable Dp on
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> index 1e27301584a4..0bc3d248c266 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> @@ -27,16 +27,17 @@
>  #include "cdn-dp-core.h"
>  #include "cdn-dp-reg.h"
>
> -static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
> +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
> +			      struct cdn_dp_port *port);
> +
> +static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge *bridge)
>  {
> -	return container_of(bridge, struct cdn_dp_device, bridge);
> +	return container_of(bridge, struct cdn_dp_bridge, bridge);
>  }
>
> -static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
> +static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
>  {
> -	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> -
> -	return container_of(rkencoder, struct cdn_dp_device, encoder);
> +	return bridge_to_dp_bridge(bridge)->parent;
>  }
>
>  #define GRF_SOC_CON9		0x6224
> @@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
>  static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
>  {
>  	struct cdn_dp_port *port;
> -	int i, lanes;
> +	int i, lanes[MAX_PHY];
>
>  	for (i = 0; i < dp->ports; i++) {
>  		port = dp->port[i];
> -		lanes = cdn_dp_get_port_lanes(port);
> -		if (lanes)
> +		lanes[i] = cdn_dp_get_port_lanes(port);
> +		if (!dp->next_bridge_valid)
>  			return port;
>  	}
> +
> +	if (dp->next_bridge_valid) {
> +		/* If more than one port is available, pick the last active port */
> +		if (dp->active_port > 0 && lanes[dp->active_port])
> +			return dp->port[dp->active_port];
> +
> +		/* If the last active port is not available, pick an available port in order */
> +		for (i = 0; i < dp->bridge_count; i++) {
> +			if (lanes[i])
> +				return dp->port[i];
> +		}
> +	}
> +
>  	return NULL;
>  }
>
> @@ -253,12 +267,45 @@ static const struct drm_edid *
>  cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)
>  {
>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
> -	const struct drm_edid *drm_edid;
> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
> +	struct cdn_dp_port *port = dp->port[dp_bridge->id];
> +	struct cdn_dp_port *prev_port;
> +	const struct drm_edid *drm_edid = NULL;
> +	int i, ret;
>
>  	mutex_lock(&dp->lock);
> +
> +	/* More than one port is available */
> +	if (dp->bridge_count > 1 && !port->phy_enabled) {
> +		for (i = 0; i < dp->bridge_count; i++) {
> +			/* Another port already enable */
> +			if (dp->bridge_list[i] != dp_bridge && dp->bridge_list[i]->enabled)
> +				goto get_cache;
> +			/* Find already enabled port */
> +			if (dp->port[i]->phy_enabled)
> +				prev_port = dp->port[i];
> +		}
> +
> +		/* Switch to current port */
> +		if (prev_port) {
> +			ret = cdn_dp_switch_port(dp, prev_port, port);
> +			if (ret)
> +				goto get_cache;
> +		}
> +	}
> +
>  	drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
> +	/* replace edid cache */
> +	if (dp->edid_cache[dp_bridge->id])
> +		drm_edid_free(dp->edid_cache[dp_bridge->id]);
> +	dp->edid_cache[dp_bridge->id] = drm_edid_dup(drm_edid);
> +
>  	mutex_unlock(&dp->lock);
> +	return drm_edid;
>
> +get_cache:
> +	drm_edid = drm_edid_dup(dp->edid_cache[dp_bridge->id]);
> +	mutex_unlock(&dp->lock);
>  	return drm_edid;
>  }
>
> @@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
>  			 const struct drm_display_info *display_info,
>  			 const struct drm_display_mode *mode)
>  {
> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
>  	u32 requested, actual, rate, sink_max, source_max = 0;
>  	u8 lanes, bpc;
>
>  	/* If DP is disconnected, every mode is invalid */
> -	if (!dp->connected)
> +	if (!dp_bridge->connected || !dp->connected)
>  		return MODE_BAD;
>
>  	switch (display_info->bpc) {
> @@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
>  	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
>  }
>
> +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
> +			      struct cdn_dp_port *port)
> +{
> +	int ret;
> +
> +	if (dp->active)
> +		return 0;
> +
> +	ret = cdn_dp_disable_phy(dp, prev_port);
> +	if (ret)
> +		goto out;
> +	ret = cdn_dp_enable_phy(dp, port);
> +	if (ret)
> +		goto out;
> +
> +	ret = cdn_dp_get_sink_capability(dp);
> +	if (ret) {
> +		cdn_dp_disable_phy(dp, port);
> +		goto out;
> +	}
> +
> +	dp->active = true;
> +	dp->lanes = port->lanes;
> +
> +	if (!cdn_dp_check_link_status(dp)) {
> +		dev_info(dp->dev, "Connected with sink; re-train link\n");
> +
> +		ret = cdn_dp_train_link(dp);
> +		if (ret) {
> +			dev_err(dp->dev, "Training link failed: %d\n", ret);
> +			goto out;
> +		}
> +
> +		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
> +		if (ret) {
> +			dev_err(dp->dev, "Failed to idle video %d\n", ret);
> +			goto out;
> +		}
> +
> +		ret = cdn_dp_config_video(dp);
> +		if (ret)
> +			dev_err(dp->dev, "Failed to configure video: %d\n", ret);
> +	}
> +
> +out:
> +	return ret;
> +}
> +
>  static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
>  				       struct drm_display_info *display_info)
>  {
> @@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
>  static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)
>  {
>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>  	struct drm_connector *connector;
>  	int ret, val;
>
> @@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>
>  	cdn_dp_display_info_update(dp, &connector->display_info);
>
> -	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.encoder);
> +	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->encoder.encoder);
>  	if (ret < 0) {
>  		DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
>  		return;
> @@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>
>  	mutex_lock(&dp->lock);
>
> +	if (dp->next_bridge_valid)
> +		dp->active_port = dp_bridge->id;
> +
>  	ret = cdn_dp_enable(dp);
>  	if (ret) {
>  		DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
> @@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>  		goto out;
>  	}
>
> +	dp_bridge->enabled = true;
>  out:
>  	mutex_unlock(&dp->lock);
>  }
> @@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>  static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)
>  {
>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>  	int ret;
>
>  	mutex_lock(&dp->lock);
> +	dp_bridge->enabled = false;
>
>  	if (dp->active) {
>  		ret = cdn_dp_disable(dp);
> @@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge *bridge,
>  	return ret;
>  }
>
> +static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge,
> +			   enum drm_connector_status status)
> +{
> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
> +	struct cdn_dp_device *dp = bridge_to_dp(bridge);
> +
> +	dp->bridge_list[dp_bridge->id]->connected = status == connector_status_connected;
> +	schedule_work(&dp->event_work);
> +}
> +
>  static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
>  	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
>  	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> @@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
>  	.atomic_disable = cdn_dp_bridge_atomic_disable,
>  	.mode_valid = cdn_dp_bridge_mode_valid,
>  	.mode_set = cdn_dp_bridge_mode_set,
> +	.hpd_notify = cdn_dp_bridge_hpd_notify,
>
>  	.dp_audio_prepare = cdn_dp_audio_prepare,
>  	.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
> @@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
>  {
>  	struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
>  						event_work);
> -	int ret;
> +	bool connected;
> +	int i, ret;
>
>  	mutex_lock(&dp->lock);
>
> @@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
>
>  out:
>  	mutex_unlock(&dp->lock);
> -	drm_bridge_hpd_notify(&dp->bridge,
> -			      dp->connected ? connector_status_connected
> -					    : connector_status_disconnected);
> +	for (i = 0; i < dp->bridge_count; i++) {
> +		connected = dp->connected && dp->bridge_list[i]->connected;
> +		drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge,
> +				      connected ? connector_status_connected
> +						: connector_status_disconnected);
> +	}
>  }
>
>  static int cdn_dp_pd_event(struct notifier_block *nb,
> @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>  	return NOTIFY_DONE;
>  }
>
> -static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
> +static int cdn_bridge_add(struct device *dev,
> +			  struct drm_bridge *bridge,
> +			  struct drm_bridge *next_bridge,
> +			  struct drm_encoder *encoder)
>  {
>  	struct cdn_dp_device *dp = dev_get_drvdata(dev);
> -	struct drm_encoder *encoder;
> +	struct drm_device *drm_dev = dp->drm_dev;
> +	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;
>  	struct drm_connector *connector;
> -	struct cdn_dp_port *port;
> -	struct drm_device *drm_dev = data;
> -	int ret, i;
> -
> -	ret = cdn_dp_parse_dt(dp);
> -	if (ret < 0)
> -		return ret;
> -
> -	dp->drm_dev = drm_dev;
> -	dp->connected = false;
> -	dp->active = false;
> -	dp->active_port = -1;
> -	dp->fw_loaded = false;
> -
> -	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
> -
> -	encoder = &dp->encoder.encoder;
> +	int ret;
>
>  	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
>  							     dev->of_node);
> @@ -1002,26 +1108,35 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>
>  	drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
>
> -	dp->bridge.ops =
> -			DRM_BRIDGE_OP_DETECT |
> -			DRM_BRIDGE_OP_EDID |
> -			DRM_BRIDGE_OP_HPD |
> -			DRM_BRIDGE_OP_DP_AUDIO;
> -	dp->bridge.of_node = dp->dev->of_node;
> -	dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
> -	dp->bridge.hdmi_audio_dev = dp->dev;
> -	dp->bridge.hdmi_audio_max_i2s_playback_channels = 8;
> -	dp->bridge.hdmi_audio_spdif_playback = 1;
> -	dp->bridge.hdmi_audio_dai_port = -1;
> -
> -	ret = devm_drm_bridge_add(dev, &dp->bridge);
> +	bridge->ops =
> +		DRM_BRIDGE_OP_DETECT |
> +		DRM_BRIDGE_OP_EDID |
> +		DRM_BRIDGE_OP_HPD |
> +		DRM_BRIDGE_OP_DP_AUDIO;
> +	bridge->of_node = dp->dev->of_node;
> +	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
> +	bridge->hdmi_audio_dev = dp->dev;
> +	bridge->hdmi_audio_max_i2s_playback_channels = 8;
> +	bridge->hdmi_audio_spdif_playback = 1;
> +	bridge->hdmi_audio_dai_port = -1;
> +
> +	ret = devm_drm_bridge_add(dev, bridge);
>  	if (ret)
>  		return ret;
>
> -	ret = drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>  	if (ret)
>  		return ret;
>
> +	if (next_bridge) {
> +		ret = drm_bridge_attach(encoder, next_bridge, bridge,
> +					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +		if (ret)
> +			return ret;
> +
> +		last_bridge = drm_bridge_chain_get_last_bridge(bridge->encoder);
> +	}
> +
>  	connector = drm_bridge_connector_init(drm_dev, encoder);
>  	if (IS_ERR(connector)) {
>  		ret = PTR_ERR(connector);
> @@ -1029,8 +1144,100 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>  		return ret;
>  	}
>
> +	if (last_bridge)
> +		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
> +
>  	drm_connector_attach_encoder(connector, encoder);
>
> +	return 0;
> +}
> +
> +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
> +{
> +	struct device_node *np = dp->dev->of_node;
> +	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
> +	struct drm_bridge *bridge;
> +	int count = 0;
> +	int ret = 0;
> +	int i;
> +
> +	/* If device use extcon, do not use hpd bridge */
> +	for (i = 0; i < dp->ports; i++) {
> +		if (dp->port[i]->extcon) {
> +			dp->bridge_count = 1;
> +			return 0;
> +		}
> +	}
> +
> +	/* One endpoint may correspond to one next bridge. */
> +	for_each_of_graph_port_endpoint(port, dp_ep) {
> +		struct device_node *next_bridge_node __free(device_node) =
> +			of_graph_get_remote_port_parent(dp_ep);
> +
> +		bridge = of_drm_find_bridge(next_bridge_node);
> +		if (!bridge) {
> +			ret = -EPROBE_DEFER;
> +			goto out;
> +		}
> +
> +		drm_bridge_get(bridge);
> +		dp->next_bridge_valid = true;
> +		dp->next_bridge_list[count] = bridge;

Correct, but the drm_bridge_get() slightly far away from the assignement is
a bit misleading. I hadn't seen it initially so I suspected a missing get.

I suggest to do it in a single statement, for clarity:

		dp->next_bridge_list[count] = bridgedrm_bridge_get(bridge);

With that changed, at least for the bridge lifetime aspects, you can add to
the next version my:

 Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

^ permalink raw reply

* Re: [PATCH v2 2/4] phy: axiado: add Axiado eMMC PHY driver
From: Tzu-Hao Wei @ 2026-03-02 18:02 UTC (permalink / raw)
  To: Vinod Koul
  Cc: SriNavmani A, Prasad Bolisetty, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-phy, devicetree,
	linux-arm-kernel, linux-kernel, openbmc
In-Reply-To: <aaGv3q8czkrKyW42@vaman>

On 2/27/2026 6:53 AM, Vinod Koul wrote:
>> --- /dev/null
>> +++ b/drivers/phy/axiado/phy-axiado-emmc.c
>> @@ -0,0 +1,221 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Axiado eMMC PHY driver
>> + *
>> + * Copyright (C) 2017 Arasan Chip Systems Inc.
>> + * Copyright (C) 2022-2025 Axiado Corporation (or its affiliates).
> 
> 2026
> 
Thanks. Will fix in the next version.

>> + *
>> + * Based on Arasan Driver (sdhci-pci-arasan.c)
>> + * sdhci-pci-arasan.c - Driver for Arasan PCI Controller with integrated phy.
>> + */
>> +#include <linux/bitfield.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/iopoll.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +
>> +/* Arasan eMMC 5.1 - PHY configuration registers */
>> +#define CAP_REG_IN_S1_LSB            0x00
>> +#define CAP_REG_IN_S1_MSB            0x04
>> +#define PHY_CTRL_1                   0x38
>> +#define PHY_CTRL_2                   0x3C
> 
> smaller hex case please, here and other places
> 
Thanks. Will fix in the next version.

>> +#define PHY_CTRL_3                   0x40
>> +#define STATUS                               0x50
>> +
>> +#define DLL_ENBL     BIT(26)
>> +#define RTRIM_EN     BIT(21)
>> +#define PDB_ENBL     BIT(23)
>> +#define RETB_ENBL    BIT(1)
>> +
>> +#define REN_STRB     BIT(27)
>> +#define REN_CMD              BIT(12)
>> +#define REN_DAT0     BIT(13)
>> +#define REN_DAT1     BIT(14)
>> +#define REN_DAT2     BIT(15)
>> +#define REN_DAT3     BIT(16)
>> +#define REN_DAT4     BIT(17)
>> +#define REN_DAT5     BIT(18)
>> +#define REN_DAT6     BIT(19)
>> +#define REN_DAT7     BIT(20)
>> +#define REN_CMD_EN   (REN_CMD | REN_DAT0 | REN_DAT1 | REN_DAT2 | \
>> +             REN_DAT3 | REN_DAT4 | REN_DAT5 | REN_DAT6 | REN_DAT7)
>> +
>> +/* Pull-UP Enable on CMD Line */
>> +#define PU_CMD               BIT(3)
>> +#define PU_DAT0              BIT(4)
>> +#define PU_DAT1              BIT(5)
>> +#define PU_DAT2              BIT(6)
>> +#define PU_DAT3              BIT(7)
>> +#define PU_DAT4              BIT(8)
>> +#define PU_DAT5              BIT(9)
>> +#define PU_DAT6              BIT(10)
>> +#define PU_DAT7              BIT(11)
>> +#define PU_CMD_EN (PU_CMD | PU_DAT0 | PU_DAT1 | PU_DAT2 | PU_DAT3 | \
>> +             PU_DAT4 | PU_DAT5 | PU_DAT6 | PU_DAT7)
> 
> The bit define are used only once, why not define the cmd with
> respective bits here
> 
Will replace it by
#define PU_CMD_EN GENMASK(11, 3)

>> +static const struct phy_ops axiado_emmc_phy_ops = {
>> +     .init = axiado_emmc_phy_init,
>> +     .power_on = axiado_emmc_phy_power_on,
> 
> no power_off?
> 
Thanks for reminding, will add power_off.

> --
> ~Vinod


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

^ permalink raw reply

* Re: [PATCH 0/6] phy: rockchip: samsung-hdptx: Clock fixes and API transition cleanups
From: 1und1 @ 2026-03-02 19:46 UTC (permalink / raw)
  To: Cristian Ciocaltea, Vinod Koul, Neil Armstrong, Heiko Stuebner,
	Algea Cao, Dmitry Baryshkov
  Cc: kernel, linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <20260227-hdptx-clk-fixes-v1-0-f998f2762d0f@collabora.com>

Hi Cristian,

Am Freitag, dem 27.02.2026 um 22:48 +0200 schrieb Cristian Ciocaltea:
> This series provides a set of bug fixes and cleanups for the Rockchip
> Samsung HDPTX PHY driver.
> 
> The first part of the series (i.e. PATCH 1 & 2) addresses clock rate
> calculation and synchronization issues.  Specifically, it fixes edge
> cases where the PHY PLL is pre-programmed by an external component (like
> a bootloader) or when changing the color depth (bpc) while keeping the
> modeline constant. 

as I brought up one of the mentioned edge cases with my Radxa Rock 5b booting
linux from EDK2 [1], I wanted to report that with this series applied,
everything works as expected and my issues are fixed.

Thus, feel free to add my

Tested-by: Thomas Niederprüm <dubito@online.de>

>  Because the Common Clock Framework .set_rate()
> callback might not be invoked if the pixel clock remains unchanged, this
> previously led to out-of-sync states between CCF and the actual HDMI PHY
> configuration.
> 
> The second part focuses on code cleanups and modernizing the register
> access.  Now that dw_hdmi_qp driver has fully switched to using
> phy_configure(), we can drop the deprecated TMDS rate setup workarounds
> and the restrict_rate_change flag logic.  Finally, it refactors the
> driver to consistently use standard bitfield macros.
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> Cristian Ciocaltea (6):
>       phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc
>       phy: rockchip: samsung-hdptx: Handle uncommitted PHY config changes
>       phy: rockchip: samsung-hdptx: Drop TMDS rate setup workaround
>       phy: rockchip: samsung-hdptx: Drop restrict_rate_change handling
>       phy: rockchip: samsung-hdptx: Simplify GRF access with FIELD_PREP_WM16()
>       phy: rockchip: samsung-hdptx: Consistently use bitfield macros
> 
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 215 +++++++++------------
> -
>  1 file changed, 92 insertions(+), 123 deletions(-)
> ---
> base-commit: 7d6661873f6b54c75195780a40d66bad3d482d8f
> change-id: 20260227-hdptx-clk-fixes-47426632f862
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

Best regards,

Thomas

[1]:
https://lore.kernel.org/lkml/b32164001947ba922aefb6ca86a8dc59e9323d2b.camel@online.de/

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

^ permalink raw reply

* Re: [PATCH 0/6] phy: rockchip: samsung-hdptx: Clock fixes and API transition cleanups
From: Cristian Ciocaltea @ 2026-03-02 20:25 UTC (permalink / raw)
  To: dubito, Vinod Koul, Neil Armstrong, Heiko Stuebner, Algea Cao,
	Dmitry Baryshkov
  Cc: kernel, linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <88436a35a3197393b5eb4fc49962a3b5906bf147.camel@online.de>

Hi Thomas,

On 3/2/26 9:46 PM, 1und1 wrote:
> Hi Cristian,
> 
> Am Freitag, dem 27.02.2026 um 22:48 +0200 schrieb Cristian Ciocaltea:
>> This series provides a set of bug fixes and cleanups for the Rockchip
>> Samsung HDPTX PHY driver.
>>
>> The first part of the series (i.e. PATCH 1 & 2) addresses clock rate
>> calculation and synchronization issues.  Specifically, it fixes edge
>> cases where the PHY PLL is pre-programmed by an external component (like
>> a bootloader) or when changing the color depth (bpc) while keeping the
>> modeline constant. 
> 
> as I brought up one of the mentioned edge cases with my Radxa Rock 5b booting
> linux from EDK2 [1], I wanted to report that with this series applied,
> everything works as expected and my issues are fixed.
> 
> Thus, feel free to add my
> 
> Tested-by: Thomas Niederprüm <dubito@online.de>

Thanks for (re)testing!

Regards,
Cristian

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

^ permalink raw reply

* Re: [PATCH RESEND2 net-next 0/8] net: stmmac: qcom-ethqos: further serdes reorganisation
From: Jakub Kicinski @ 2026-03-02 23:29 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Russell King (Oracle), Andrew Lunn, Alexandre Torgue, Andrew Lunn,
	David S. Miller, Eric Dumazet, linux-arm-kernel, linux-arm-msm,
	linux-phy, linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
	Paolo Abeni, Vinod Koul
In-Reply-To: <20260301120824.ot53bhv7z7kn5lfd@skbuf>

On Sun, 1 Mar 2026 14:08:24 +0200 Vladimir Oltean wrote:
> > I don't recall us ever making a "dirty tag" on net-next which would
> > propagate few 100s of netdev patches into someone else's tree :S
> > IDK how Linus would react. It's the least good option IMO.  
> 
> Just for my curiosity, what difference would it make to him?

The PHY PR will contain a bunch of networking code.

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

^ permalink raw reply

* Re: [PATCH RESEND2 net-next 0/8] net: stmmac: qcom-ethqos: further serdes reorganisation
From: Jakub Kicinski @ 2026-03-02 23:57 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller,
	Eric Dumazet, linux-arm-kernel, linux-arm-msm, linux-phy,
	linux-stm32, Mohd Ayaan Anwar, Neil Armstrong, netdev,
	Paolo Abeni, Vinod Koul
In-Reply-To: <aaRBjWhP4-7Kru9D@shell.armlinux.org.uk>

On Sun, 1 Mar 2026 13:39:25 +0000 Russell King (Oracle) wrote:
> On Sat, Feb 28, 2026 at 08:31:11AM -0800, Jakub Kicinski wrote:
> > On Fri, 27 Feb 2026 16:55:56 -0800 Jakub Kicinski wrote:  
> > > Yes, that's what I thought but then I saw the other thread..  
> > 
> > Trying to apply this now but stmmac parts don't apply on Linus's tree,
> > and Vinod wants a tag :( What do we do?   
> 
> The problem will be that this series has dependencies on the first
> batch of qcom-ethqos patches, particularly:
> cd0aa6515350 ("net: stmmac: pass interface mode into fix_mac_speed()
> method")
> b560938163db ("net: stmmac: qcom-ethqos: pass phy interface mode to
> configs")
> fb42f19e671f ("net: stmmac: qcom-ethqos: move SerDes speed
> configuration")
> 
> which enables the change in the third patch of this series - and
> without the third patch, none of the following patches in this series
> can be applied.
> 
> I'm not sure what to suggest either.

Alright, I think the best we can do here is to merge patch 2 
in a "stable tag" way. The rest will have to go via net-next.

I applied patch 2, Russell please rebase the rest on net-next 
and repost. Patch 2 should disappear. I don't want to merge it
now as is without an explicit nod from Vinod. He did ask for 
a tag and we won't provide one.

Vinod / Vladimir, to merge the "stable tag" of patch 2:

tag_name=phy-qcom-sgmii-eth-add-set_mode-and-validate-methods
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
git tag $tag_name 0e8147f4da00
git merge $tag_name
git tag -d $tag_name

I think this should work.

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

^ permalink raw reply

* Re: [PATCH RESEND2 net-next 0/8] net: stmmac: qcom-ethqos: further serdes reorganisation
From: patchwork-bot+netdevbpf @ 2026-03-03  0:00 UTC (permalink / raw)
  To: Russell King
  Cc: andrew, alexandre.torgue, andrew+netdev, davem, edumazet, kuba,
	linux-arm-kernel, linux-arm-msm, linux-phy, linux-stm32,
	mohd.anwar, neil.armstrong, netdev, pabeni, vkoul
In-Reply-To: <aaDSJAc-x2-klvHJ@shell.armlinux.org.uk>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 26 Feb 2026 23:07:16 +0000 you wrote:
> This is part 2 of the qcom-ethqos series, part 1 has now been merged.
> 
> This part of the series focuses on the generic PHY driver, but these
> changes have dependencies on the ethernet driver, hence why
> it will need to go via net-next. Furthermore, subsequent changes
> depend on these patches.
> 
> [...]

Here is the summary with links:
  - [RESEND2,net-next,1/8] net: stmmac: qcom-ethqos: move ethqos_set_serdes_speed()
    (no matching commit)
  - [RESEND2,net-next,2/8] phy: qcom-sgmii-eth: add .set_mode() and .validate() methods
    https://git.kernel.org/netdev/net-next/c/4ff5801f45b4
  - [RESEND2,net-next,3/8] net: stmmac: qcom-ethqos: convert to use phy_set_mode_ext()
    (no matching commit)
  - [RESEND2,net-next,4/8] phy: qcom-sgmii-eth: remove .set_speed() implementation
    (no matching commit)
  - [RESEND2,net-next,5/8] phy: qcom-sgmii-eth: use PHY interface mode for SerDes settings
    (no matching commit)
  - [RESEND2,net-next,6/8] phy: qcom-sgmii-eth: remove qcom_dwmac_sgmii_phy_interface()
    (no matching commit)
  - [RESEND2,net-next,7/8] phy: qcom-sgmii-eth: relax order of .power_on() vs .set_mode*()
    (no matching commit)
  - [RESEND2,net-next,8/8] net: stmmac: qcom-ethqos: remove phy_set_mode_ext() after phy_power_on()
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

^ permalink raw reply

* Re: [PATCH v14 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
From: Chaoyi Chen @ 2026-03-03  0:44 UTC (permalink / raw)
  To: Luca Ceresoli
  Cc: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov, Peter Chen,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
	Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
	Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
	devicetree, linux-kernel, linux-phy, linux-arm-kernel,
	linux-rockchip, dri-devel
In-Reply-To: <DGSHIQOB2YTB.1559SD1YLGT7P@bootlin.com>

Hi Luca,

On 3/3/2026 1:49 AM, Luca Ceresoli wrote:
> On Mon Jan 19, 2026 at 8:30 AM CET, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>>
>> The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
>> the CDN-DP can be switched to output to one of the PHYs. If both ports
>> are plugged into DP, DP will select the first port for output.
>>
>> This patch adds support for multiple bridges, enabling users to flexibly
>> select the output port. For each PHY port, a separate encoder and bridge
>> are registered.
>>
>> The change is based on the DRM AUX HPD bridge, rather than the
>> extcon approach. This requires the DT to correctly describe the
>> connections between the first bridge in bridge chain and DP
>> controller. For example, the bridge chain may be like this:
>>
>> PHY aux birdge -> fsa4480 analog audio switch bridge ->
>> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge
>>
>> In this case, the connection relationships among the PHY aux bridge
>> and the DP contorller need to be described in DT.
>>
>> In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
>> determines whether to register one or two bridges.
>>
>> Since there is only one DP controller, only one of the PHY ports can
>> output at a time. The key is how to switch between different PHYs,
>> which is handled by cdn_dp_switch_port() and cdn_dp_enable().
>>
>> There are two cases:
>>
>> 1. Neither bridge is enabled. In this case, both bridges can
>> independently read the EDID, and the PHY port may switch before
>> reading the EDID.
>>
>> 2. One bridge is already enabled. In this case, other bridges are not
>> allowed to read the EDID. So we will try to return the cached EDID.
>>
>> Since the scenario of two ports plug in at the same time is rare,
>> I don't have a board which support two TypeC connector to test this.
>> Therefore, I tested forced switching on a single PHY port, as well as
>> output using a fake PHY port alongside a real PHY port.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>> ---
>>
>> (no changes since v11)
>>
>> Changes in v10:
>> - Fix refcount usage of drm_bridge.
>> - Remove unused cdn_dp_next_bridge type.
>>
>> Changes in v9:
>> - Select DRM_AUX_HPD_BRIDGE when using DP driver.
>>
>> (no changes since v7)
>>
>> Changes in v6:
>> - Rename some variable names.
>> - Attach the DP bridge to the next bridge.
>>
>> Changes in v5:
>> - By parsing the HPD bridge chain, set the connector's of_node to the
>> of_node corresponding to the USB-C connector.
>> - Return EDID cache when other port is already enabled.
>> ---
>>
>>  drivers/gpu/drm/rockchip/Kconfig       |   1 +
>>  drivers/gpu/drm/rockchip/cdn-dp-core.c | 325 ++++++++++++++++++++-----
>>  drivers/gpu/drm/rockchip/cdn-dp-core.h |  18 +-
>>  3 files changed, 287 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
>> index b7b025814e72..10d9f29a3d44 100644
>> --- a/drivers/gpu/drm/rockchip/Kconfig
>> +++ b/drivers/gpu/drm/rockchip/Kconfig
>> @@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP
>>  	select DRM_DISPLAY_HELPER
>>  	select DRM_BRIDGE_CONNECTOR
>>  	select DRM_DISPLAY_DP_HELPER
>> +	select DRM_AUX_HPD_BRIDGE
>>  	help
>>  	  This selects support for Rockchip SoC specific extensions
>>  	  for the cdn DP driver. If you want to enable Dp on
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> index 1e27301584a4..0bc3d248c266 100644
>> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> @@ -27,16 +27,17 @@
>>  #include "cdn-dp-core.h"
>>  #include "cdn-dp-reg.h"
>>
>> -static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
>> +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
>> +			      struct cdn_dp_port *port);
>> +
>> +static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge *bridge)
>>  {
>> -	return container_of(bridge, struct cdn_dp_device, bridge);
>> +	return container_of(bridge, struct cdn_dp_bridge, bridge);
>>  }
>>
>> -static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
>> +static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
>>  {
>> -	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
>> -
>> -	return container_of(rkencoder, struct cdn_dp_device, encoder);
>> +	return bridge_to_dp_bridge(bridge)->parent;
>>  }
>>
>>  #define GRF_SOC_CON9		0x6224
>> @@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
>>  static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
>>  {
>>  	struct cdn_dp_port *port;
>> -	int i, lanes;
>> +	int i, lanes[MAX_PHY];
>>
>>  	for (i = 0; i < dp->ports; i++) {
>>  		port = dp->port[i];
>> -		lanes = cdn_dp_get_port_lanes(port);
>> -		if (lanes)
>> +		lanes[i] = cdn_dp_get_port_lanes(port);
>> +		if (!dp->next_bridge_valid)
>>  			return port;
>>  	}
>> +
>> +	if (dp->next_bridge_valid) {
>> +		/* If more than one port is available, pick the last active port */
>> +		if (dp->active_port > 0 && lanes[dp->active_port])
>> +			return dp->port[dp->active_port];
>> +
>> +		/* If the last active port is not available, pick an available port in order */
>> +		for (i = 0; i < dp->bridge_count; i++) {
>> +			if (lanes[i])
>> +				return dp->port[i];
>> +		}
>> +	}
>> +
>>  	return NULL;
>>  }
>>
>> @@ -253,12 +267,45 @@ static const struct drm_edid *
>>  cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)
>>  {
>>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
>> -	const struct drm_edid *drm_edid;
>> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>> +	struct cdn_dp_port *port = dp->port[dp_bridge->id];
>> +	struct cdn_dp_port *prev_port;
>> +	const struct drm_edid *drm_edid = NULL;
>> +	int i, ret;
>>
>>  	mutex_lock(&dp->lock);
>> +
>> +	/* More than one port is available */
>> +	if (dp->bridge_count > 1 && !port->phy_enabled) {
>> +		for (i = 0; i < dp->bridge_count; i++) {
>> +			/* Another port already enable */
>> +			if (dp->bridge_list[i] != dp_bridge && dp->bridge_list[i]->enabled)
>> +				goto get_cache;
>> +			/* Find already enabled port */
>> +			if (dp->port[i]->phy_enabled)
>> +				prev_port = dp->port[i];
>> +		}
>> +
>> +		/* Switch to current port */
>> +		if (prev_port) {
>> +			ret = cdn_dp_switch_port(dp, prev_port, port);
>> +			if (ret)
>> +				goto get_cache;
>> +		}
>> +	}
>> +
>>  	drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
>> +	/* replace edid cache */
>> +	if (dp->edid_cache[dp_bridge->id])
>> +		drm_edid_free(dp->edid_cache[dp_bridge->id]);
>> +	dp->edid_cache[dp_bridge->id] = drm_edid_dup(drm_edid);
>> +
>>  	mutex_unlock(&dp->lock);
>> +	return drm_edid;
>>
>> +get_cache:
>> +	drm_edid = drm_edid_dup(dp->edid_cache[dp_bridge->id]);
>> +	mutex_unlock(&dp->lock);
>>  	return drm_edid;
>>  }
>>
>> @@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
>>  			 const struct drm_display_info *display_info,
>>  			 const struct drm_display_mode *mode)
>>  {
>> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
>>  	u32 requested, actual, rate, sink_max, source_max = 0;
>>  	u8 lanes, bpc;
>>
>>  	/* If DP is disconnected, every mode is invalid */
>> -	if (!dp->connected)
>> +	if (!dp_bridge->connected || !dp->connected)
>>  		return MODE_BAD;
>>
>>  	switch (display_info->bpc) {
>> @@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
>>  	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
>>  }
>>
>> +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
>> +			      struct cdn_dp_port *port)
>> +{
>> +	int ret;
>> +
>> +	if (dp->active)
>> +		return 0;
>> +
>> +	ret = cdn_dp_disable_phy(dp, prev_port);
>> +	if (ret)
>> +		goto out;
>> +	ret = cdn_dp_enable_phy(dp, port);
>> +	if (ret)
>> +		goto out;
>> +
>> +	ret = cdn_dp_get_sink_capability(dp);
>> +	if (ret) {
>> +		cdn_dp_disable_phy(dp, port);
>> +		goto out;
>> +	}
>> +
>> +	dp->active = true;
>> +	dp->lanes = port->lanes;
>> +
>> +	if (!cdn_dp_check_link_status(dp)) {
>> +		dev_info(dp->dev, "Connected with sink; re-train link\n");
>> +
>> +		ret = cdn_dp_train_link(dp);
>> +		if (ret) {
>> +			dev_err(dp->dev, "Training link failed: %d\n", ret);
>> +			goto out;
>> +		}
>> +
>> +		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
>> +		if (ret) {
>> +			dev_err(dp->dev, "Failed to idle video %d\n", ret);
>> +			goto out;
>> +		}
>> +
>> +		ret = cdn_dp_config_video(dp);
>> +		if (ret)
>> +			dev_err(dp->dev, "Failed to configure video: %d\n", ret);
>> +	}
>> +
>> +out:
>> +	return ret;
>> +}
>> +
>>  static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
>>  				       struct drm_display_info *display_info)
>>  {
>> @@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
>>  static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)
>>  {
>>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
>> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>>  	struct drm_connector *connector;
>>  	int ret, val;
>>
>> @@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>>
>>  	cdn_dp_display_info_update(dp, &connector->display_info);
>>
>> -	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.encoder);
>> +	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->encoder.encoder);
>>  	if (ret < 0) {
>>  		DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
>>  		return;
>> @@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>>
>>  	mutex_lock(&dp->lock);
>>
>> +	if (dp->next_bridge_valid)
>> +		dp->active_port = dp_bridge->id;
>> +
>>  	ret = cdn_dp_enable(dp);
>>  	if (ret) {
>>  		DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
>> @@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>>  		goto out;
>>  	}
>>
>> +	dp_bridge->enabled = true;
>>  out:
>>  	mutex_unlock(&dp->lock);
>>  }
>> @@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
>>  static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)
>>  {
>>  	struct cdn_dp_device *dp = bridge_to_dp(bridge);
>> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>>  	int ret;
>>
>>  	mutex_lock(&dp->lock);
>> +	dp_bridge->enabled = false;
>>
>>  	if (dp->active) {
>>  		ret = cdn_dp_disable(dp);
>> @@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge *bridge,
>>  	return ret;
>>  }
>>
>> +static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge,
>> +			   enum drm_connector_status status)
>> +{
>> +	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
>> +	struct cdn_dp_device *dp = bridge_to_dp(bridge);
>> +
>> +	dp->bridge_list[dp_bridge->id]->connected = status == connector_status_connected;
>> +	schedule_work(&dp->event_work);
>> +}
>> +
>>  static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
>>  	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
>>  	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
>> @@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
>>  	.atomic_disable = cdn_dp_bridge_atomic_disable,
>>  	.mode_valid = cdn_dp_bridge_mode_valid,
>>  	.mode_set = cdn_dp_bridge_mode_set,
>> +	.hpd_notify = cdn_dp_bridge_hpd_notify,
>>
>>  	.dp_audio_prepare = cdn_dp_audio_prepare,
>>  	.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
>> @@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
>>  {
>>  	struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
>>  						event_work);
>> -	int ret;
>> +	bool connected;
>> +	int i, ret;
>>
>>  	mutex_lock(&dp->lock);
>>
>> @@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
>>
>>  out:
>>  	mutex_unlock(&dp->lock);
>> -	drm_bridge_hpd_notify(&dp->bridge,
>> -			      dp->connected ? connector_status_connected
>> -					    : connector_status_disconnected);
>> +	for (i = 0; i < dp->bridge_count; i++) {
>> +		connected = dp->connected && dp->bridge_list[i]->connected;
>> +		drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge,
>> +				      connected ? connector_status_connected
>> +						: connector_status_disconnected);
>> +	}
>>  }
>>
>>  static int cdn_dp_pd_event(struct notifier_block *nb,
>> @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>>  	return NOTIFY_DONE;
>>  }
>>
>> -static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>> +static int cdn_bridge_add(struct device *dev,
>> +			  struct drm_bridge *bridge,
>> +			  struct drm_bridge *next_bridge,
>> +			  struct drm_encoder *encoder)
>>  {
>>  	struct cdn_dp_device *dp = dev_get_drvdata(dev);
>> -	struct drm_encoder *encoder;
>> +	struct drm_device *drm_dev = dp->drm_dev;
>> +	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;
>>  	struct drm_connector *connector;
>> -	struct cdn_dp_port *port;
>> -	struct drm_device *drm_dev = data;
>> -	int ret, i;
>> -
>> -	ret = cdn_dp_parse_dt(dp);
>> -	if (ret < 0)
>> -		return ret;
>> -
>> -	dp->drm_dev = drm_dev;
>> -	dp->connected = false;
>> -	dp->active = false;
>> -	dp->active_port = -1;
>> -	dp->fw_loaded = false;
>> -
>> -	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
>> -
>> -	encoder = &dp->encoder.encoder;
>> +	int ret;
>>
>>  	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
>>  							     dev->of_node);
>> @@ -1002,26 +1108,35 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>>
>>  	drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
>>
>> -	dp->bridge.ops =
>> -			DRM_BRIDGE_OP_DETECT |
>> -			DRM_BRIDGE_OP_EDID |
>> -			DRM_BRIDGE_OP_HPD |
>> -			DRM_BRIDGE_OP_DP_AUDIO;
>> -	dp->bridge.of_node = dp->dev->of_node;
>> -	dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
>> -	dp->bridge.hdmi_audio_dev = dp->dev;
>> -	dp->bridge.hdmi_audio_max_i2s_playback_channels = 8;
>> -	dp->bridge.hdmi_audio_spdif_playback = 1;
>> -	dp->bridge.hdmi_audio_dai_port = -1;
>> -
>> -	ret = devm_drm_bridge_add(dev, &dp->bridge);
>> +	bridge->ops =
>> +		DRM_BRIDGE_OP_DETECT |
>> +		DRM_BRIDGE_OP_EDID |
>> +		DRM_BRIDGE_OP_HPD |
>> +		DRM_BRIDGE_OP_DP_AUDIO;
>> +	bridge->of_node = dp->dev->of_node;
>> +	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
>> +	bridge->hdmi_audio_dev = dp->dev;
>> +	bridge->hdmi_audio_max_i2s_playback_channels = 8;
>> +	bridge->hdmi_audio_spdif_playback = 1;
>> +	bridge->hdmi_audio_dai_port = -1;
>> +
>> +	ret = devm_drm_bridge_add(dev, bridge);
>>  	if (ret)
>>  		return ret;
>>
>> -	ret = drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>  	if (ret)
>>  		return ret;
>>
>> +	if (next_bridge) {
>> +		ret = drm_bridge_attach(encoder, next_bridge, bridge,
>> +					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +		if (ret)
>> +			return ret;
>> +
>> +		last_bridge = drm_bridge_chain_get_last_bridge(bridge->encoder);
>> +	}
>> +
>>  	connector = drm_bridge_connector_init(drm_dev, encoder);
>>  	if (IS_ERR(connector)) {
>>  		ret = PTR_ERR(connector);
>> @@ -1029,8 +1144,100 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>>  		return ret;
>>  	}
>>
>> +	if (last_bridge)
>> +		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
>> +
>>  	drm_connector_attach_encoder(connector, encoder);
>>
>> +	return 0;
>> +}
>> +
>> +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
>> +{
>> +	struct device_node *np = dp->dev->of_node;
>> +	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
>> +	struct drm_bridge *bridge;
>> +	int count = 0;
>> +	int ret = 0;
>> +	int i;
>> +
>> +	/* If device use extcon, do not use hpd bridge */
>> +	for (i = 0; i < dp->ports; i++) {
>> +		if (dp->port[i]->extcon) {
>> +			dp->bridge_count = 1;
>> +			return 0;
>> +		}
>> +	}
>> +
>> +	/* One endpoint may correspond to one next bridge. */
>> +	for_each_of_graph_port_endpoint(port, dp_ep) {
>> +		struct device_node *next_bridge_node __free(device_node) =
>> +			of_graph_get_remote_port_parent(dp_ep);
>> +
>> +		bridge = of_drm_find_bridge(next_bridge_node);
>> +		if (!bridge) {
>> +			ret = -EPROBE_DEFER;
>> +			goto out;
>> +		}
>> +
>> +		drm_bridge_get(bridge);
>> +		dp->next_bridge_valid = true;
>> +		dp->next_bridge_list[count] = bridge;
> 
> Correct, but the drm_bridge_get() slightly far away from the assignement is
> a bit misleading. I hadn't seen it initially so I suspected a missing get.
> 
> I suggest to do it in a single statement, for clarity:
> 
> 		dp->next_bridge_list[count] = bridgedrm_bridge_get(bridge);
>

I think the bridgedrm_bridge_get here seems to be a typo?

Anyway, thank you very much for your efforts on the bridge lifetime.
I will fix this in the next version :)

> With that changed, at least for the bridge lifetime aspects, you can add to
> the next version my:
> 
>  Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> 
> Luca
> 
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
> 

-- 
Best, 
Chaoyi

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

^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema
From: Vijay Kumar Tumati @ 2026-03-03  1:51 UTC (permalink / raw)
  To: Bryan O'Donoghue, Vinod Koul, Kishon Vijay Abraham I,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong
  Cc: Bryan O'Donoghue, Vladimir Zapolskiy, linux-arm-msm,
	linux-phy, linux-media, devicetree, linux-kernel
In-Reply-To: <20260226-x1e-csi2-phy-v3-1-11e608759410@linaro.org>

Hi Bryan,

On 2/26/2026 4:34 AM, Bryan O'Donoghue wrote:
> Add a base schema initially compatible with x1e80100 to describe MIPI CSI2
> PHY devices.
> 
> The hardware can support both C-PHY and D-PHY modes. The CSIPHY devices
> have their own pinouts on the SoC as well as their own individual voltage
> rails.
> 
> The need to model voltage rails on a per-PHY basis leads us to define
> CSIPHY devices as individual nodes.
> 
> Two nice outcomes in terms of schema and DT arise from this change.
> 
> 1. The ability to define on a per-PHY basis voltage rails.
> 2. The ability to require those voltage.
> 
> We have had a complete bodge upstream for this where a single set of
> voltage rail for all CSIPHYs has been buried inside of CAMSS.
> 
> Much like the I2C bus which is dedicated to Camera sensors - the CCI bus in
> CAMSS parlance, the CSIPHY devices should be individually modelled.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>   .../bindings/phy/qcom,x1e80100-csi2-phy.yaml       | 114 +++++++++++++++++++++
>   1 file changed, 114 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
> new file mode 100644
> index 0000000000000..c937d26ccbda9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
> @@ -0,0 +1,114 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/qcom,x1e80100-csi2-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm CSI2 PHY
> +
> +maintainers:
> +  - Bryan O'Donoghue <bod@kernel.org>
> +
> +description:
> +  Qualcomm MIPI CSI2 C-PHY/D-PHY combination PHY. Connects MIPI CSI2 sensors
> +  to Qualcomm's Camera CSI Decoder. The PHY supports both C-PHY and D-PHY
> +  modes.
> +
> +properties:
> +  compatible:
> +    const: qcom,x1e80100-csi2-phy
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#phy-cells":
> +    const: 1
> +
> +  clocks:
> +    maxItems: 4
> +
> +  clock-names:
> +    items:
> +      - const: csiphy
> +      - const: csiphy_timer
> +      - const: camnoc_axi
> +      - const: cpas_ahb
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  operating-points-v2:
> +    maxItems: 1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  vdda-0p8-supply:
> +    description: Phandle to a 0.8V regulator supply to a PHY.
> +
> +  vdda-1p2-supply:
> +    description: Phandle to 1.2V regulator supply to a PHY.
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#phy-cells"
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - operating-points-v2
> +  - power-domains
> +  - vdda-0p8-supply
> +  - vdda-1p2-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/qcom,x1e80100-camcc.h>
> +    #include <dt-bindings/clock/qcom,x1e80100-gcc.h>
> +    #include <dt-bindings/phy/phy.h>
> +
> +    csiphy@ace4000 {
> +        compatible = "qcom,x1e80100-csi2-phy";
> +        reg = <0x0ace4000 0x2000>;
> +        #phy-cells = <1>;
> +
> +        clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
> +                 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
> +                 <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>,
> +                 <&camcc CAM_CC_CPAS_AHB_CLK>;
> +        clock-names = "csiphy",
> +                      "csiphy_timer",
> +                      "camnoc_axi",
> +                      "cpas_ahb";
> +
> +        operating-points-v2 = <&csiphy_opp_table>;
> +
> +        interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
> +
> +        power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
As we are cleaning up the PHY device nodes, we should consider fixing 
the power domains as well. Although TOP GDSC is defined as a power 
domain, it is not the power source for the PHY devices. Rather, it is 
the MMCX, MXC and optionally MXA based on the architecture (Refer to 
'Voltage rail' column for PHY clocks in IPCAT). There is no
parent-child relationship between the TOP GDSC and these in the clock 
driver and it was just working as the required power rails are getting 
enabled by/for other MM devices.
> +
> +        vdda-0p8-supply = <&vreg_l2c_0p8>;
> +        vdda-1p2-supply = <&vreg_l1c_1p2>;
> +    };
> +
> +    csiphy_opp_table: opp-table-csiphy {
> +        compatible = "operating-points-v2";
> +
> +        opp-300000000 {
> +            opp-hz = /bits/ 64 <300000000>;
> +            required-opps = <&rpmhpd_opp_low_svs_d1>;
> +        };
> +
> +        opp-400000000 {
> +            opp-hz = /bits/ 64 <400000000>;
> +            required-opps = <&rpmhpd_opp_low_svs>;
> +        };
> +
> +        opp-480000000 {
> +            opp-hz = /bits/ 64 <480000000>;
> +            required-opps = <&rpmhpd_opp_low_svs>;
> +        };
> +    };
> 
Thanks,
Vijay.

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

^ permalink raw reply

* Re: [PATCH v3 5/6] drm/mediatek: dsi: Add compatible for mt8167-dsi
From: CK Hu (胡俊光) @ 2026-03-03  7:56 UTC (permalink / raw)
  To: l.scorcia@gmail.com
  Cc: robh@kernel.org, Chunfeng Yun (云春峰),
	simona@ffwll.ch, tzimmermann@suse.de, mripard@kernel.org,
	AngeloGioacchino Del Regno, linux-kernel@vger.kernel.org,
	linux-mediatek@lists.infradead.org,
	dri-devel@lists.freedesktop.org, chunkuang.hu@kernel.org,
	vkoul@kernel.org, devicetree@vger.kernel.org,
	linux-phy@lists.infradead.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, conor+dt@kernel.org, airlied@gmail.com,
	linux-arm-kernel@lists.infradead.org,
	maarten.lankhorst@linux.intel.com, matthias.bgg@gmail.com,
	neil.armstrong@linaro.org
In-Reply-To: <CAORyz2Ki5aPNbcY5-_mRwFgwT46VN_pRV2iP7z7x3snzrbKz=g@mail.gmail.com>

On Wed, 2026-02-25 at 09:15 +0100, Luca Leonardo Scorcia wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> > > The mt8167 DSI controller is fully compatible with the one found in
> > > mt2701. Device tree documentation is already present upstream.
> > 
> > If mt8167 DSI is fully compatible with mt2701 DSI, I think the binding document and device tree should be modified.
> > In device tree,
> > 
> >     compatible = "mediatek,mt8167-dsi", "mediatek,mt2701-dsi";
> > 
> > And this patch is not necessary.
> 
> Hi, if I understand your review correctly that's what v2 [1] of this
> patch did, but the change was rejected during review.
> 
> As far as I can see there is no win-win solution here. This tricky
> situation derives from the fact that in last year's submissions the
> change was only partially merged - the bindings went upstream while
> the driver did not, and now we have to work around this. In v3 I tried
> to address the issue by actually implementing what the binding
> document says.
> I'll be happy to resubmit v4 but I need to know what's the consensus here.

You mean Krzysztof's comment?
He has two comment.
The first is 'remove'. You actually not remove "mediatek,mt8167-dsi". You change it.
The second is about fallback. I'm also not sure why he says it's NAK. Also a bad wording?
After Angelo's comment, Krzysztof does not response.
I also do not know what Krzysztof think.
I agree with Angelo. Single "mediatek,mt8167-dsi" does not reflect the hardware compatible but fallback does.
Maybe describe more information (hardware) to Krzysztof, and ask what's the better way to do.

Regards,
CK

> 
> Thanks!
> 
> [1] https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/ff920a7cc94f2b0c03d4bb55142030fded30d07c.1771258407.git.l.scorcia@gmail.com/__;!!CTRNKA9wMg0ARbw!lIBnCRkybM1oxoARb70JlLMPlXHKqW9dwSmVqXGsvj3LE9hsWuINkPgtrlr8Jl8-atOvzYoMjtavHOr3$
> 
> > > 
> > > Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_dsi.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > index af4871de9e4c..ad10e86b161d 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > @@ -1301,6 +1301,7 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
> > > 
> > >  static const struct of_device_id mtk_dsi_of_match[] = {
> > >         { .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data },
> > > +       { .compatible = "mediatek,mt8167-dsi", .data = &mt2701_dsi_driver_data },
> > >         { .compatible = "mediatek,mt8173-dsi", .data = &mt8173_dsi_driver_data },
> > >         { .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data },
> > >         { .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data },
> > > --
> > > 2.43.0
> > > 
> > > 
> --
> Luca Leonardo Scorcia
> l.scorcia@gmail.com

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

^ permalink raw reply

* Re: [PATCH v7 20/23] scsi: ufs: mediatek: Back up idle timer in per-instance struct
From: Peter Wang (王信友) @ 2026-03-03  8:01 UTC (permalink / raw)
  To: chu.stanley@gmail.com, robh@kernel.org,
	Chunfeng Yun (云春峰), kishon@kernel.org,
	James.Bottomley@HansenPartnership.com, bvanassche@acm.org,
	AngeloGioacchino Del Regno,
	Chaotian Jing (井朝天), conor+dt@kernel.org,
	lgirdwood@gmail.com, nicolas.frattaroli@collabora.com,
	vkoul@kernel.org, krzk+dt@kernel.org, p.zabel@pengutronix.de,
	alim.akhtar@samsung.com, neil.armstrong@linaro.org,
	matthias.bgg@gmail.com, avri.altman@wdc.com, broonie@kernel.org,
	martin.petersen@oracle.com
  Cc: linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org,
	Louis-Alexis Eyraud, kernel@collabora.com
In-Reply-To: <48e8f40b-f5f3-42b5-a97b-7a25d1dc0fb8@collabora.com>

On Thu, 2026-02-26 at 11:36 +0100, AngeloGioacchino Del Regno wrote:
> 
> Okay, does "saved_auto_hibern8_idle_tmr" sound good for you instead?
> 
> Regards,
> Angelo
> 
> 

Hi AngeloGioacchino,

I’m fine with saved_auto_hibern8_idle_tmr, but it is more 
verbose compared to saved_ahit.

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

^ permalink raw reply

* Re: [PATCH v7 16/23] scsi: ufs: mediatek: Clean up logging prints
From: Peter Wang (王信友) @ 2026-03-03  8:06 UTC (permalink / raw)
  To: chu.stanley@gmail.com, robh@kernel.org,
	Chunfeng Yun (云春峰), kishon@kernel.org,
	James.Bottomley@hansenpartnership.com, bvanassche@acm.org,
	AngeloGioacchino Del Regno,
	Chaotian Jing (井朝天), conor+dt@kernel.org,
	lgirdwood@gmail.com, nicolas.frattaroli@collabora.com,
	vkoul@kernel.org, krzk+dt@kernel.org, p.zabel@pengutronix.de,
	alim.akhtar@samsung.com, neil.armstrong@linaro.org,
	matthias.bgg@gmail.com, avri.altman@wdc.com, broonie@kernel.org,
	martin.petersen@oracle.com
  Cc: linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org,
	Louis-Alexis Eyraud, kernel@collabora.com
In-Reply-To: <84f22f00-e3eb-4ea5-999e-260c81f29338@collabora.com>

On Thu, 2026-02-26 at 11:45 +0100, AngeloGioacchino Del Regno wrote:
> Sorry Peter, but I'd argue that the users don't care about how much
> and when
> their UFS device resets. Users just want to use a device, without
> caring
> about any implementation detail.
> The spirit is: "radio silence as long as everything works good".
> 
> Power users might want to check the kernel log in a problematic
> scenario to
> seek for a message that says that "something went horribly wrong",
> but other
> than developers, nobody cares about when UFS resets.
> 
>  From a developer standpoint, I do agree with you in that we do *not*
> want to
> see device resets occurring repeatedly, but we're talking about a
> user here.
> 
> See it like this... imagine if all of the device drivers in the Linux
> kernel
> would say "device reset done": how many devices are present in one
> SoC (of
> course, ignoring subdevices on a board)?
> 
> Of all those many devices, if all of them would print a message
> saying that
> their reset is done (and operation is ok), the kernel log would get
> quite a
> bit clogged, you'd need to have a bigger RAM carveout just for ..
> well, the
> kernel log itself, and then you'd have to grep the log, hoping to
> find the
> one single line that helps you finding an issue that you're having.
> 
> This is the reason why keeping any message that is not exactly a
> *single*
> indication of an error (so, an actual issue) as a dev_dbg() is a
> sensible
> thing to do (and of course, with dynamic debug in the kernel, you can
> always
> activate that on-the-fly without recompiling to verify functionality
> should
> you have any immediate doubt).
> 
> So while I agree about your reasons, I very strongly disagree about
> having
> this message as a dev_info(), nor anything else that is not dev_dbg()
> really.
> 
> Regards,
> Angelo

Hi AngeloGioacchino,

I am not sure if you know that when UFS encounters an error,
such as a UIC error or timeout, some errors can be so severe
that they cannot be recovered without a reset. In these cases,
we need to perform error handling or recovery by resetting 
the device.

I agree that "radio silence is preferable as long as everything
works well." However, users may sometimes wonder why their 
device (phone, tablet, laptop, etc.) shows good IO performance 
in tests, but the actual user experience is poor (laggy).
This log can provide users with an explanation for IO lag
during usage.

I also agree that many devices are present in a single SoC, but
I don't think there is much reset information throughout the system.
Each device should ensure that the likelihood of a reset (error) 
is minimized.

Thanks.
Peter

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

^ permalink raw reply

* Re: [PATCH v14 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
From: Luca Ceresoli @ 2026-03-03  8:52 UTC (permalink / raw)
  To: Chaoyi Chen
  Cc: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov, Peter Chen,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
	Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
	Diederik de Haas, Peter Robinson, linux-usb, devicetree,
	linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
	dri-devel
In-Reply-To: <601a8b51-7411-429d-91a1-0633cabce9ee@rock-chips.com>

Hello Chaoyi,

On Tue Mar 3, 2026 at 1:44 AM CET, Chaoyi Chen wrote:
>>> +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
>>> +{
>>> +	struct device_node *np = dp->dev->of_node;
>>> +	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
>>> +	struct drm_bridge *bridge;
>>> +	int count = 0;
>>> +	int ret = 0;
>>> +	int i;
>>> +
>>> +	/* If device use extcon, do not use hpd bridge */
>>> +	for (i = 0; i < dp->ports; i++) {
>>> +		if (dp->port[i]->extcon) {
>>> +			dp->bridge_count = 1;
>>> +			return 0;
>>> +		}
>>> +	}
>>> +
>>> +	/* One endpoint may correspond to one next bridge. */
>>> +	for_each_of_graph_port_endpoint(port, dp_ep) {
>>> +		struct device_node *next_bridge_node __free(device_node) =
>>> +			of_graph_get_remote_port_parent(dp_ep);
>>> +
>>> +		bridge = of_drm_find_bridge(next_bridge_node);
>>> +		if (!bridge) {
>>> +			ret = -EPROBE_DEFER;
>>> +			goto out;
>>> +		}
>>> +
>>> +		drm_bridge_get(bridge);
>>> +		dp->next_bridge_valid = true;
>>> +		dp->next_bridge_list[count] = bridge;
>>
>> Correct, but the drm_bridge_get() slightly far away from the assignement is
>> a bit misleading. I hadn't seen it initially so I suspected a missing get.
>>
>> I suggest to do it in a single statement, for clarity:
>>
>> 		dp->next_bridge_list[count] = bridgedrm_bridge_get(bridge);
>>
>
> I think the bridgedrm_bridge_get here seems to be a typo?

Oops, of course! :)

As you probably guessed, I was meaning:

		dp->next_bridge_list[count] = drm_bridge_get(bridge);


> Anyway, thank you very much for your efforts on the bridge lifetime.
> I will fix this in the next version :)

Thanks!

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema
From: Bryan O'Donoghue @ 2026-03-03  9:27 UTC (permalink / raw)
  To: Vijay Kumar Tumati, Bryan O'Donoghue, Vinod Koul,
	Kishon Vijay Abraham I, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong
  Cc: Vladimir Zapolskiy, linux-arm-msm, linux-phy, linux-media,
	devicetree, linux-kernel
In-Reply-To: <c85fe457-c140-441c-93ed-342dce32e604@oss.qualcomm.com>

On 03/03/2026 01:51, Vijay Kumar Tumati wrote:
> Hi Bryan,
> 
> On 2/26/2026 4:34 AM, Bryan O'Donoghue wrote:
>> Add a base schema initially compatible with x1e80100 to describe MIPI CSI2
>> PHY devices.
>>
>> The hardware can support both C-PHY and D-PHY modes. The CSIPHY devices
>> have their own pinouts on the SoC as well as their own individual voltage
>> rails.
>>
>> The need to model voltage rails on a per-PHY basis leads us to define
>> CSIPHY devices as individual nodes.
>>
>> Two nice outcomes in terms of schema and DT arise from this change.
>>
>> 1. The ability to define on a per-PHY basis voltage rails.
>> 2. The ability to require those voltage.
>>
>> We have had a complete bodge upstream for this where a single set of
>> voltage rail for all CSIPHYs has been buried inside of CAMSS.
>>
>> Much like the I2C bus which is dedicated to Camera sensors - the CCI bus in
>> CAMSS parlance, the CSIPHY devices should be individually modelled.
>>
>> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>> ---
>>    .../bindings/phy/qcom,x1e80100-csi2-phy.yaml       | 114 +++++++++++++++++++++
>>    1 file changed, 114 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
>> new file mode 100644
>> index 0000000000000..c937d26ccbda9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
>> @@ -0,0 +1,114 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/qcom,x1e80100-csi2-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm CSI2 PHY
>> +
>> +maintainers:
>> +  - Bryan O'Donoghue <bod@kernel.org>
>> +
>> +description:
>> +  Qualcomm MIPI CSI2 C-PHY/D-PHY combination PHY. Connects MIPI CSI2 sensors
>> +  to Qualcomm's Camera CSI Decoder. The PHY supports both C-PHY and D-PHY
>> +  modes.
>> +
>> +properties:
>> +  compatible:
>> +    const: qcom,x1e80100-csi2-phy
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  "#phy-cells":
>> +    const: 1
>> +
>> +  clocks:
>> +    maxItems: 4
>> +
>> +  clock-names:
>> +    items:
>> +      - const: csiphy
>> +      - const: csiphy_timer
>> +      - const: camnoc_axi
>> +      - const: cpas_ahb
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  operating-points-v2:
>> +    maxItems: 1
>> +
>> +  power-domains:
>> +    maxItems: 1
>> +
>> +  vdda-0p8-supply:
>> +    description: Phandle to a 0.8V regulator supply to a PHY.
>> +
>> +  vdda-1p2-supply:
>> +    description: Phandle to 1.2V regulator supply to a PHY.
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - "#phy-cells"
>> +  - clocks
>> +  - clock-names
>> +  - interrupts
>> +  - operating-points-v2
>> +  - power-domains
>> +  - vdda-0p8-supply
>> +  - vdda-1p2-supply
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/clock/qcom,x1e80100-camcc.h>
>> +    #include <dt-bindings/clock/qcom,x1e80100-gcc.h>
>> +    #include <dt-bindings/phy/phy.h>
>> +
>> +    csiphy@ace4000 {
>> +        compatible = "qcom,x1e80100-csi2-phy";
>> +        reg = <0x0ace4000 0x2000>;
>> +        #phy-cells = <1>;
>> +
>> +        clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
>> +                 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
>> +                 <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>,
>> +                 <&camcc CAM_CC_CPAS_AHB_CLK>;
>> +        clock-names = "csiphy",
>> +                      "csiphy_timer",
>> +                      "camnoc_axi",
>> +                      "cpas_ahb";
>> +
>> +        operating-points-v2 = <&csiphy_opp_table>;
>> +
>> +        interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
>> +
>> +        power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
> As we are cleaning up the PHY device nodes, we should consider fixing
> the power domains as well. Although TOP GDSC is defined as a power
> domain, it is not the power source for the PHY devices. Rather, it is
> the MMCX, MXC and optionally MXA based on the architecture (Refer to
> 'Voltage rail' column for PHY clocks in IPCAT). 

Feel free to send me a qcom laptop and I will :)

 From memory though I _thought_ only the TOP was required for the PHY. 
I'd be grateful if you could confirm yourself in ipcat.

- TITAN_TOP_GDSC
- MXC
- MMCX
- MXA - first time I've heard of this rail, from memory I don't remember
         having seen this in ipcat when I could do so.

There is no
> parent-child relationship between the TOP GDSC and these in the clock
> driver and it was just working as the required power rails are getting
> enabled by/for other MM devices.

Well only the GDSC is supplied by the clock controller.

>> +
>> +        vdda-0p8-supply = <&vreg_l2c_0p8>;
>> +        vdda-1p2-supply = <&vreg_l1c_1p2>;
>> +    };
>> +
>> +    csiphy_opp_table: opp-table-csiphy {
>> +        compatible = "operating-points-v2";
>> +
>> +        opp-300000000 {
>> +            opp-hz = /bits/ 64 <300000000>;
>> +            required-opps = <&rpmhpd_opp_low_svs_d1>;
>> +        };
>> +
>> +        opp-400000000 {
>> +            opp-hz = /bits/ 64 <400000000>;
>> +            required-opps = <&rpmhpd_opp_low_svs>;
>> +        };
>> +
>> +        opp-480000000 {
>> +            opp-hz = /bits/ 64 <480000000>;
>> +            required-opps = <&rpmhpd_opp_low_svs>;
>> +        };
>> +    };
>>
> Thanks,
> Vijay.


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

^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema
From: Bryan O'Donoghue @ 2026-03-03  9:30 UTC (permalink / raw)
  To: Bryan O'Donoghue, Vijay Kumar Tumati, Bryan O'Donoghue,
	Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong
  Cc: Vladimir Zapolskiy, linux-arm-msm, linux-phy, linux-media,
	devicetree, linux-kernel
In-Reply-To: <c85fe457-c140-441c-93ed-342dce32e604@oss.qualcomm.com>

On 03/03/2026 09:27, Bryan O'Donoghue wrote:
> - MXA - first time I've heard of this rail, from memory I don't remember
>          having seen this in ipcat when I could do so.

Yeah no MXA isn't a required vote.

https://lore.kernel.org/linux-arm-msm/9ff1645f-b2c9-4c1a-ae2d-96af416b08d9@oss.qualcomm.com/

---
bod


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

^ permalink raw reply

* Re: [PATCH v7 20/23] scsi: ufs: mediatek: Back up idle timer in per-instance struct
From: Nicolas Frattaroli @ 2026-03-03 10:15 UTC (permalink / raw)
  To: chu.stanley@gmail.com, robh@kernel.org,
	Chunfeng Yun (云春峰), kishon@kernel.org,
	James.Bottomley@HansenPartnership.com, bvanassche@acm.org,
	AngeloGioacchino Del Regno,
	Chaotian Jing (井朝天), conor+dt@kernel.org,
	lgirdwood@gmail.com, vkoul@kernel.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, alim.akhtar@samsung.com,
	neil.armstrong@linaro.org, matthias.bgg@gmail.com,
	avri.altman@wdc.com, broonie@kernel.org,
	martin.petersen@oracle.com, Peter Wang (王信友)
  Cc: linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org,
	Louis-Alexis Eyraud, kernel@collabora.com
In-Reply-To: <0bef3e1592e64f74e6a6fd8ef59129ac71b307e4.camel@mediatek.com>

On Tuesday, 3 March 2026 09:01:14 Central European Standard Time Peter Wang (王信友) wrote:
> On Thu, 2026-02-26 at 11:36 +0100, AngeloGioacchino Del Regno wrote:
> > 
> > Okay, does "saved_auto_hibern8_idle_tmr" sound good for you instead?
> > 
> > Regards,
> > Angelo
> > 
> > 
> 
> Hi AngeloGioacchino,
> 
> I’m fine with saved_auto_hibern8_idle_tmr, but it is more 
> verbose compared to saved_ahit.
> 
> Thanks
> Peter
> 

Yeah no I won't change this, this is pointless bikeshedding.



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

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add vdda-refgen supply for Glymur
From: Konrad Dybcio @ 2026-03-03 11:14 UTC (permalink / raw)
  To: Qiang Yu, Dmitry Baryshkov
  Cc: Krzysztof Kozlowski, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, linux-phy,
	devicetree, linux-kernel
In-Reply-To: <aaVkpKZcrNM7k4Xm@hu-qianyu-lv.qualcomm.com>

On 3/2/26 11:21 AM, Qiang Yu wrote:
> On Fri, Feb 13, 2026 at 07:47:36PM +0200, Dmitry Baryshkov wrote:
>> On Wed, Feb 11, 2026 at 07:32:23PM -0800, Qiang Yu wrote:
>>> On Mon, Feb 09, 2026 at 09:06:23AM +0100, Krzysztof Kozlowski wrote:
>>>> On Sun, Feb 08, 2026 at 08:49:39PM -0800, Qiang Yu wrote:
>>>>> The PCIe QMP PHYs on Glymur require stable reference voltage provided by
>>>>> refgen. The refgen itself requires two separate power supplies:
>>>>> vdda-refgen0p9 and vdda-refgen1p2.
>>>>>
>>>>> Since there is no dedicated driver for REFGEN, add vdda-refgen0p9-supply
>>>>
>>>> How does the driver matter for the bindings? If I add dedicated driver
>>>> for refgen, then I change the bindings?
>>>
>>> Yeah, I know that dt-bindings should describe hardware, not software. But
>>> what I meant to say is that the refgen is different from qref which is
>>> controlled via TCSR registers and its LDOs are requested to vote in
>>> tcsrcc driver. The refgen doesn't required register setting and it doesn't
>>> have dedicated driver, so we vote its LDOs in phy driver. I will avoid
>>> this statement in next version.
>>
>> I must admit, I could not find references to the refgen in any of Glymur
>> PCIe-related HPGs.
>>
>>>
>>>>
>>>> There is qcom,sc8280xp-refgen-regulator so why there cannot be
>>>> qcom,x1e-refgen-regulator?
>>>
>>> I think we can and it seems better because the refgen for pcie phy also
>>> supplies reference voltage to other modules like usb. But I checked the
>>> qcom-refgen-regulator.c, it contains some register settings and there is
>>> no LDOs voting. I'm not sure what does those register do, maybe Konrad
>>> can provide some backgroud.
>>
>> Those regs provide voting for refgen, because on those platforms DSI
>> block doesn't have a hardware vote for refgen.
> 
> Hi Konrad, Dmitry
> 
> I tried to model the reference voltage as a fixed regulator but the fixed
> regulator driver only supports a single vin-supply. However, the refgen
> block requires two separate power supplies (1.2V and 0.9V LDOs).
> 
> Would it be appropriate to modify the qcom-refgen-regulator.c driver to
> handle LDO voting for both the 1.2V and 0.9V supplies? In the regulator's
> enable/disable callbacks, we could vote for and unvote these two LDOs
> instead of performing register operations.

Wait, so you want to associate the MMIO-controlled refgen's driver with
a dummy regulator that takes 2 supplies? I didn't catch that part earlier,
that's not great..

Or do we actually have access to the MMIO of *this* refgen and can control
it (except we don't do that today because X Y Z)?

Konrad

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

^ permalink raw reply

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

On 2/28/26 11:05 PM, 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.
> 
> Note: the suspend/resume callbacks were already gating the enable/disable
> of this clock only on init_count and not usb_init_count!
> 
> Signed-off-by: Val Packett <val@packett.cool>
> ---
> See https://lore.kernel.org/all/389ca5d3-a698-4dac-911c-39ba057e3d17@oss.qualcomm.com/ for more info.
> BTW https://lore.kernel.org/all/20260205160240.748371-2-loic.poulain@oss.qualcomm.com/ helped with coldplug.

I think that's a fluke, you shouldn't see any real-world impact from
that patch

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

^ permalink raw reply

* Re: [PATCH v9 1/2] dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY
From: Bo Gan @ 2026-03-03 11:46 UTC (permalink / raw)
  To: Yulin Lu, vkoul, neil.armstrong, robh, krzk+dt, conor+dt, p.zabel,
	linux-phy, devicetree, linux-kernel
  Cc: ningyu, linmin, fenglin
In-Reply-To: <20260205082129.1482-1-luyulin@eswincomputing.com>

Hi Yulin,

Can your team share the dt and driver for &hspcrg? I want to do some
testing with your latest v15 clock patchset on my P550 w/ SATA. W/o
&hspcrg, the SATA phy can't be enabled, hence SATA drive doesn't work.

Bo

On 2/5/26 00:21, Yulin Lu wrote:
> Document the SATA PHY on the EIC7700 SoC platform,
> describing its usage.
> 
> Signed-off-by: Yulin Lu <luyulin@eswincomputing.com>
> ---
>   .../bindings/phy/eswin,eic7700-sata-phy.yaml  | 92 +++++++++++++++++++
>   1 file changed, 92 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
> new file mode 100644
> index 000000000000..fc7dbac77acf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
> @@ -0,0 +1,92 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/eswin,eic7700-sata-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Eswin EIC7700 SoC SATA PHY
> +
> +maintainers:
> +  - Yulin Lu <luyulin@eswincomputing.com>
> +  - Huan He <hehuan1@eswincomputing.com>
> +
> +properties:
> +  compatible:
> +    const: eswin,eic7700-sata-phy
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    const: phy
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: port
> +      - const: phy
> +
> +  eswin,tx-amplitude-tuning:
> +    description: This adjusts the transmitter amplitude signal, and its value
> +      is derived from eye diagram tuning. The three values correspond to Gen1,
> +      Gen2, and Gen3 parameters respectively.
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    items:
> +      - description: Gen1 parameter.
> +        minimum: 0
> +        maximum: 0x7f
> +      - description: Gen2 parameter.
> +        minimum: 0
> +        maximum: 0x7f
> +      - description: Gen3 parameter.
> +        minimum: 0
> +        maximum: 0x7f
> +    default: [0, 0, 0]
> +
> +  eswin,tx-preemph-tuning:
> +    description: This adjusts the transmitter de-emphasis signal, and its value
> +      is derived from eye diagram tuning. The three values correspond to Gen1,
> +      Gen2, and Gen3 parameters respectively.
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    items:
> +      - description: Gen1 parameter.
> +        minimum: 0
> +        maximum: 0x3f
> +      - description: Gen2 parameter.
> +        minimum: 0
> +        maximum: 0x3f
> +      - description: Gen3 parameter.
> +        minimum: 0
> +        maximum: 0x3f
> +    default: [0, 0, 0]
> +
> +  "#phy-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    sata-phy@50440300 {
> +        compatible = "eswin,eic7700-sata-phy";
> +        reg = <0x50440300 0x40>;
> +        clocks = <&hspcrg 17>;
> +        clock-names = "phy";
> +        resets = <&hspcrg 0>, <&hspcrg 1>;
> +        reset-names = "port", "phy";
> +        #phy-cells = <0>;
> +    };


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

^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema
From: Konrad Dybcio @ 2026-03-03 12:34 UTC (permalink / raw)
  To: Bryan O'Donoghue, Bryan O'Donoghue, Vijay Kumar Tumati,
	Bryan O'Donoghue, Vinod Koul, Kishon Vijay Abraham I,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong
  Cc: Vladimir Zapolskiy, linux-arm-msm, linux-phy, linux-media,
	devicetree, linux-kernel
In-Reply-To: <676e2a9f-d274-40fa-988f-e9388ba40f71@nxsw.ie>

On 3/3/26 10:30 AM, Bryan O'Donoghue wrote:
> On 03/03/2026 09:27, Bryan O'Donoghue wrote:
>> - MXA - first time I've heard of this rail, from memory I don't remember
>>          having seen this in ipcat when I could do so.
> 
> Yeah no MXA isn't a required vote.

That depends on the use case.

MXA is always-on (that's the 'A' in the name, as opposed to 'C'
for 'Collapsible'), but it's not always at the required performance
state (svs, nom, etc.). For some clock controllers specifically, there
is no need to put them into the picture, as the rail may be unconnected
altogether, or only used for some retention mechanisms (which only
require the rail to be enabled and nothing more)

Konrad

> 
> https://lore.kernel.org/linux-arm-msm/9ff1645f-b2c9-4c1a-ae2d-96af416b08d9@oss.qualcomm.com/
> 
> ---
> bod
> 
> 

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

^ permalink raw reply


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