All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Damon Ding" <damon.ding@rock-chips.com>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-phy@lists.infradead.org, robh@kernel.org,
	conor+dt@kernel.org, vkoul@kernel.org, neil.armstrong@linaro.org,
	olteanv@gmail.com
Subject: Re: [PATCH v2 4/6] phy: rockchip: Add support for Naneng eDP phy
Date: Mon, 19 Oct 2026 10:37:31 +0000	[thread overview]
Message-ID: <sashiko-outbox-177004@kernel.org> (raw)
In-Reply-To: <20261019102824.3157044-5-damon.ding@rock-chips.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] phy: rockchip: missing set_lanes handling in rockchip_edp_phy_configure()
- [Medium] phy: rockchip: uninitialized val read in rockchip_edp_phy_enabled()
--

commit d07a3a0e3533b84cdc67b6de45db340e9d9898c9
Author: Damon Ding <damon.ding@rock-chips.com>

phy: rockchip: Add support for Naneng eDP phy

This commit adds a driver for the Rockchip eDP transmitter PHY with the
NaNeng IP block found on the RK3568 SoC, controlled via the eDP PHY GRF
syscon regmap.

> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-edp.c b/drivers/phy/rockchip/phy-rockchip-naneng-edp.c
> new file mode 100644
> index 0000000000000..a407714f639a7
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-edp.c

[ ... ]

> +static int rockchip_edp_phy_set_voltages(struct rockchip_edp_phy *edpphy,
> +					 struct phy_configure_opts_dp *dp)
> +{
> +	u8 lane;
> +
> +	for (lane = 0; lane < dp->lanes; lane++)
> +		rockchip_edp_phy_set_voltage(edpphy, dp, lane);
> +
> +	return 0;
> +}
> +
> +static int rockchip_edp_phy_set_rate(struct rockchip_edp_phy *edpphy,
> +				     struct phy_configure_opts_dp *dp)
> +{
> +	u32 value;
> +	int ret;

[ ... ]

> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON0, FIELD_PREP_WM16(EDP_PHY_PD_PLL_MASK, 0));
> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON0,
> +		     FIELD_PREP_WM16(EDP_PHY_TX_PD_MASK, ~GENMASK(dp->lanes - 1, 0)));
> +	ret = regmap_read_poll_timeout(edpphy->grf, EDP_PHY_GRF_STATUS0,
> +				       value, value & PLL_RDY, 100, 1000);
> +	if (ret) {
> +		dev_err(edpphy->dev, "Failed to wait for PHY PLL ready: %d\n", ret);
> +		return ret;
> +	}
> +
> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON5, FIELD_PREP_WM16(EDP_PHY_TX_MODE_MASK, 0x0));
> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON0,
> +		     FIELD_PREP_WM16(EDP_PHY_TX_IDLE_MASK, ~GENMASK(dp->lanes - 1, 0)));
> +
> +	return 0;
> +}
> +
> +static int rockchip_edp_phy_verify_config(struct rockchip_edp_phy *edpphy,
> +					  struct phy_configure_opts_dp *dp)
> +{
> +	int i;
> +
> +	/* If changing link rate was required, verify it's supported. */
> +	if (dp->set_rate) {
> +		switch (dp->link_rate) {
> +		case 1620:
> +		case 2700:
> +			/* valid bit rate */
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (dp->set_lanes) {
> +		/* Verify lane count. */
> +		switch (dp->lanes) {
> +		case 1:
> +		case 2:
> +		case 4:
> +			/* valid lane count. */
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +
> +	/*
> +	 * If changing voltages is required, check swing and pre-emphasis
> +	 * levels, per-lane.
> +	 */
> +	if (dp->set_voltages) {
> +		/* Lane count verified previously. */
> +		for (i = 0; i < dp->lanes; i++) {
> +			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
> +				return -EINVAL;
> +
> +			/*
> +			 * Sum of voltage swing and pre-emphasis levels cannot
> +			 * exceed 3.
> +			 */
> +			if (dp->voltage[i] + dp->pre[i] > 3)
> +				return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int rockchip_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = rockchip_edp_phy_verify_config(edpphy, &opts->dp);
> +	if (ret) {
> +		dev_err(edpphy->dev, "Invalid params for phy configure\n");
> +		return ret;
> +	}
> +
> +	if (opts->dp.set_rate) {
> +		ret = rockchip_edp_phy_set_rate(edpphy, &opts->dp);
> +		if (ret) {
> +			dev_err(edpphy->dev, "Failed to set rate\n");
> +			return ret;
> +		}
> +	}
> +
> +	if (opts->dp.set_voltages) {
> +		ret = rockchip_edp_phy_set_voltages(edpphy, &opts->dp);
> +		if (ret) {
> +			dev_err(edpphy->dev, "Failed to set voltages\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}

[Severity: High]
How does rockchip_edp_phy_configure() handle callers that issue separate
phy_configure() calls for rate, lane count, and voltage levels?

Looking at drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c, the Analogix DP
bridge issues three separate phy_configure() calls, each with a
zero-initialized union phy_configure_opts:

1. analogix_dp_set_link_bandwidth() sets only phy_cfg.dp.link_rate and
phy_cfg.dp.set_rate = true, leaving phy_cfg.dp.lanes = 0:

    union phy_configure_opts phy_cfg = {0};

    phy_cfg.dp.link_rate =
        drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
    phy_cfg.dp.set_rate = true;
    ret = phy_configure(dp->phy, &phy_cfg);

When rockchip_edp_phy_set_rate() runs, dp->lanes is 0 (and unvalidated since
dp->set_lanes is false), so GENMASK(dp->lanes - 1, 0) evaluates
GENMASK(UINT_MAX, 0) when programming EDP_PHY_TX_PD_MASK and
EDP_PHY_TX_IDLE_MASK.

2. analogix_dp_set_lane_count() sets phy_cfg.dp.lanes and
phy_cfg.dp.set_lanes = true, but rockchip_edp_phy_configure() never checks
opts->dp.set_lanes, so the lane-dependent TX configuration is not applied and
the active lane count is not stored in struct rockchip_edp_phy.

3. analogix_dp_set_lane_link_training() sets phy_cfg.dp.voltage[],
phy_cfg.dp.pre[], and phy_cfg.dp.set_voltages = true, with phy_cfg.dp.lanes
left at 0. Both rockchip_edp_phy_verify_config() and
rockchip_edp_phy_set_voltages() loop up to dp->lanes, so 0 iterations run and
no voltage swing or pre-emphasis registers are written (or if a caller passes
set_voltages = true with set_lanes = false and an unvalidated dp->lanes > 4,
the loops read past the end of dp->voltage[4] and dp->pre[4]).

Should the lane-dependent TX configuration be applied in a set_lanes handler
that also stores the lane count in struct rockchip_edp_phy for set_voltages
to use?

> +static bool rockchip_edp_phy_enabled(struct rockchip_edp_phy *edpphy)
> +{
> +	u32 val;
> +
> +	regmap_read(edpphy->grf, EDP_PHY_GRF_STATUS0, &val);
> +
> +	return FIELD_GET(PLL_RDY, val);
> +}

[Severity: Medium]
What happens in rockchip_edp_phy_enabled() if regmap_read() fails?

Because val is uninitialized and the return value of regmap_read() is not
checked, FIELD_GET(PLL_RDY, val) will read an uninitialized stack variable,
which can cause rockchip_edp_phy_power_on() to return 0 early without
powering on or configuring the PHY AUX channel.

Should val be initialized to 0 (or the regmap_read() error checked)?

[ ... ]

> -- 
> 2.34.1

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019102824.3157044-1-damon.ding@rock-chips.com?part=4

WARNING: multiple messages have this Message-ID (diff)
From: sashiko-bot@kernel.org
To: "Damon Ding" <damon.ding@rock-chips.com>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-phy@lists.infradead.org, robh@kernel.org,
	conor+dt@kernel.org, vkoul@kernel.org, neil.armstrong@linaro.org,
	olteanv@gmail.com
Subject: Re: [PATCH v2 4/6] phy: rockchip: Add support for Naneng eDP phy
Date: Mon, 19 Oct 2026 10:37:31 +0000	[thread overview]
Message-ID: <sashiko-outbox-177004@kernel.org> (raw)
In-Reply-To: <20261019102824.3157044-5-damon.ding@rock-chips.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] phy: rockchip: missing set_lanes handling in rockchip_edp_phy_configure()
- [Medium] phy: rockchip: uninitialized val read in rockchip_edp_phy_enabled()
--

commit d07a3a0e3533b84cdc67b6de45db340e9d9898c9
Author: Damon Ding <damon.ding@rock-chips.com>

phy: rockchip: Add support for Naneng eDP phy

This commit adds a driver for the Rockchip eDP transmitter PHY with the
NaNeng IP block found on the RK3568 SoC, controlled via the eDP PHY GRF
syscon regmap.

> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-edp.c b/drivers/phy/rockchip/phy-rockchip-naneng-edp.c
> new file mode 100644
> index 0000000000000..a407714f639a7
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-edp.c

[ ... ]

> +static int rockchip_edp_phy_set_voltages(struct rockchip_edp_phy *edpphy,
> +					 struct phy_configure_opts_dp *dp)
> +{
> +	u8 lane;
> +
> +	for (lane = 0; lane < dp->lanes; lane++)
> +		rockchip_edp_phy_set_voltage(edpphy, dp, lane);
> +
> +	return 0;
> +}
> +
> +static int rockchip_edp_phy_set_rate(struct rockchip_edp_phy *edpphy,
> +				     struct phy_configure_opts_dp *dp)
> +{
> +	u32 value;
> +	int ret;

[ ... ]

> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON0, FIELD_PREP_WM16(EDP_PHY_PD_PLL_MASK, 0));
> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON0,
> +		     FIELD_PREP_WM16(EDP_PHY_TX_PD_MASK, ~GENMASK(dp->lanes - 1, 0)));
> +	ret = regmap_read_poll_timeout(edpphy->grf, EDP_PHY_GRF_STATUS0,
> +				       value, value & PLL_RDY, 100, 1000);
> +	if (ret) {
> +		dev_err(edpphy->dev, "Failed to wait for PHY PLL ready: %d\n", ret);
> +		return ret;
> +	}
> +
> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON5, FIELD_PREP_WM16(EDP_PHY_TX_MODE_MASK, 0x0));
> +	regmap_write(edpphy->grf, EDP_PHY_GRF_CON0,
> +		     FIELD_PREP_WM16(EDP_PHY_TX_IDLE_MASK, ~GENMASK(dp->lanes - 1, 0)));
> +
> +	return 0;
> +}
> +
> +static int rockchip_edp_phy_verify_config(struct rockchip_edp_phy *edpphy,
> +					  struct phy_configure_opts_dp *dp)
> +{
> +	int i;
> +
> +	/* If changing link rate was required, verify it's supported. */
> +	if (dp->set_rate) {
> +		switch (dp->link_rate) {
> +		case 1620:
> +		case 2700:
> +			/* valid bit rate */
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (dp->set_lanes) {
> +		/* Verify lane count. */
> +		switch (dp->lanes) {
> +		case 1:
> +		case 2:
> +		case 4:
> +			/* valid lane count. */
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +
> +	/*
> +	 * If changing voltages is required, check swing and pre-emphasis
> +	 * levels, per-lane.
> +	 */
> +	if (dp->set_voltages) {
> +		/* Lane count verified previously. */
> +		for (i = 0; i < dp->lanes; i++) {
> +			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
> +				return -EINVAL;
> +
> +			/*
> +			 * Sum of voltage swing and pre-emphasis levels cannot
> +			 * exceed 3.
> +			 */
> +			if (dp->voltage[i] + dp->pre[i] > 3)
> +				return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int rockchip_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = rockchip_edp_phy_verify_config(edpphy, &opts->dp);
> +	if (ret) {
> +		dev_err(edpphy->dev, "Invalid params for phy configure\n");
> +		return ret;
> +	}
> +
> +	if (opts->dp.set_rate) {
> +		ret = rockchip_edp_phy_set_rate(edpphy, &opts->dp);
> +		if (ret) {
> +			dev_err(edpphy->dev, "Failed to set rate\n");
> +			return ret;
> +		}
> +	}
> +
> +	if (opts->dp.set_voltages) {
> +		ret = rockchip_edp_phy_set_voltages(edpphy, &opts->dp);
> +		if (ret) {
> +			dev_err(edpphy->dev, "Failed to set voltages\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}

[Severity: High]
How does rockchip_edp_phy_configure() handle callers that issue separate
phy_configure() calls for rate, lane count, and voltage levels?

Looking at drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c, the Analogix DP
bridge issues three separate phy_configure() calls, each with a
zero-initialized union phy_configure_opts:

1. analogix_dp_set_link_bandwidth() sets only phy_cfg.dp.link_rate and
phy_cfg.dp.set_rate = true, leaving phy_cfg.dp.lanes = 0:

    union phy_configure_opts phy_cfg = {0};

    phy_cfg.dp.link_rate =
        drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
    phy_cfg.dp.set_rate = true;
    ret = phy_configure(dp->phy, &phy_cfg);

When rockchip_edp_phy_set_rate() runs, dp->lanes is 0 (and unvalidated since
dp->set_lanes is false), so GENMASK(dp->lanes - 1, 0) evaluates
GENMASK(UINT_MAX, 0) when programming EDP_PHY_TX_PD_MASK and
EDP_PHY_TX_IDLE_MASK.

2. analogix_dp_set_lane_count() sets phy_cfg.dp.lanes and
phy_cfg.dp.set_lanes = true, but rockchip_edp_phy_configure() never checks
opts->dp.set_lanes, so the lane-dependent TX configuration is not applied and
the active lane count is not stored in struct rockchip_edp_phy.

3. analogix_dp_set_lane_link_training() sets phy_cfg.dp.voltage[],
phy_cfg.dp.pre[], and phy_cfg.dp.set_voltages = true, with phy_cfg.dp.lanes
left at 0. Both rockchip_edp_phy_verify_config() and
rockchip_edp_phy_set_voltages() loop up to dp->lanes, so 0 iterations run and
no voltage swing or pre-emphasis registers are written (or if a caller passes
set_voltages = true with set_lanes = false and an unvalidated dp->lanes > 4,
the loops read past the end of dp->voltage[4] and dp->pre[4]).

Should the lane-dependent TX configuration be applied in a set_lanes handler
that also stores the lane count in struct rockchip_edp_phy for set_voltages
to use?

> +static bool rockchip_edp_phy_enabled(struct rockchip_edp_phy *edpphy)
> +{
> +	u32 val;
> +
> +	regmap_read(edpphy->grf, EDP_PHY_GRF_STATUS0, &val);
> +
> +	return FIELD_GET(PLL_RDY, val);
> +}

[Severity: Medium]
What happens in rockchip_edp_phy_enabled() if regmap_read() fails?

Because val is uninitialized and the return value of regmap_read() is not
checked, FIELD_GET(PLL_RDY, val) will read an uninitialized stack variable,
which can cause rockchip_edp_phy_power_on() to return 0 early without
powering on or configuring the PHY AUX channel.

Should val be initialized to 0 (or the regmap_read() error checked)?

[ ... ]

> -- 
> 2.34.1

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019102824.3157044-1-damon.ding@rock-chips.com?part=4

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

  reply	other threads:[~2026-10-19 10:37 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 10:28 [PATCH v2 0/6] Add eDP support for RK3568 Damon Ding
2026-10-19 10:28 ` Damon Ding
2026-10-19 10:28 ` Damon Ding
2026-10-19 10:28 ` [PATCH v2 1/6] dt-bindings: display: rockchip: analogix-dp: Add " Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28 ` [PATCH v2 2/6] dt-bindings: phy: Add rockchip,rk3568-edp-phy Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28 ` [PATCH v2 3/6] drm/bridge: analogix_dp: Add support for RK3568 Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28 ` [PATCH v2 4/6] phy: rockchip: Add support for Naneng eDP phy Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:37   ` sashiko-bot [this message]
2026-10-19 10:37     ` sashiko-bot
2026-10-19 10:28 ` [PATCH v2 5/6] drm/rockchip: analogix_dp: Add support for RK3568 Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28 ` [PATCH v2 6/6] arm64: dts: rockchip: rk356x: Add eDP controller and phy nodes Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:28   ` Damon Ding
2026-10-19 10:44   ` sashiko-bot
2026-10-19 10:44     ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-177004@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=damon.ding@rock-chips.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=neil.armstrong@linaro.org \
    --cc=olteanv@gmail.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.