[PATCH 1/5] phy: qcom: qmp-pcie: Skip PHY reset if already up

Manivannan Sadhasivam mani at kernel.org
Mon Feb 16 06:53:25 PST 2026


On Fri, Jan 09, 2026 at 04:03:37PM +0200, Dmitry Baryshkov wrote:
> On Fri, Jan 09, 2026 at 02:10:49PM +0100, Neil Armstrong wrote:
> > On 1/9/26 14:08, Dmitry Baryshkov wrote:
> > > On Fri, Jan 09, 2026 at 12:51:06PM +0530, Krishna Chaitanya Chundru wrote:
> > > > If the bootloader has already powered up the PCIe PHY, doing a full
> > > > reset and waiting for it to come up again slows down boot time.
> > > 
> > > How big is the delay caused by it?
> > > 
> > > > 
> > > > Add a check for PHY status and skip the reset steps when the PHY is
> > > > already active. In this case, only enable the required resources during
> > > > power-on. This works alongside the existing logic that skips the init
> > > > sequence.
> > > 
> > > Can we end up in a state where the bootloader has mis-setup the link? Or
> > > the link going bad because of any glitch during the bootup?
> > 
> > Good question, can we add a module parameter to force a full reset of the PHY in case
> > the bootloader is buggy ?
> 
> I'd suggest a simpler thing: if the reset was skipped, reset the PHY in
> case of an error and retry. That's also one of the reasons why I asked
> for skip_reset not to be the persistent value.
> 

I'm not sure what value would resetting the PHY provide in the case of failure.
As per this patch, skip_reset is only going to be set for platforms where
bootloader has already configured the PHY. So in the case of PHY link failure,
simply resetting the PHY won't help IMO as the PHY register contents are going
to be presistent due to nocsr_reset.

- Mani

> > 
> > > 
> > > > 
> > > > Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> > > > ---
> > > >   drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 28 ++++++++++++++++++----------
> > > >   1 file changed, 18 insertions(+), 10 deletions(-)
> > > > 
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > > > index 86b1b7e2da86a8675e3e48e90b782afb21cafd77..c93e613cf80b2612f0f225fa2125f78dbec1a33f 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > > > @@ -3153,6 +3153,7 @@ struct qmp_pcie {
> > > >   	const struct qmp_phy_cfg *cfg;
> > > >   	bool tcsr_4ln_config;
> > > >   	bool skip_init;
> > > > +	bool skip_reset;
> > > >   	void __iomem *serdes;
> > > >   	void __iomem *pcs;
> > > > @@ -4537,6 +4538,9 @@ static int qmp_pcie_init(struct phy *phy)
> > > >   		qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
> > > >   		qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
> > > > +	qmp->skip_reset = qmp->skip_init && !qphy_checkbits(pcs, cfg->regs[QPHY_PCS_STATUS],
> > > 
> > > It is definitely not a long-term state, there is no need to store it in
> > > qmp_pcie struct.
> > > 
> > > > +							    cfg->phy_status);
> > > > +
> > > >   	if (!qmp->skip_init && !cfg->tbls.serdes_num) {
> > > >   		dev_err(qmp->dev, "Init sequence not available\n");
> > > >   		return -ENODATA;
> > > > @@ -4560,13 +4564,15 @@ static int qmp_pcie_init(struct phy *phy)
> > > >   		}
> > > >   	}
> > > > -	ret = reset_control_assert(qmp->nocsr_reset);
> > > > -	if (ret) {
> > > > -		dev_err(qmp->dev, "no-csr reset assert failed\n");
> > > > -		goto err_assert_reset;
> > > > -	}
> > > > +	if (!qmp->skip_reset) {
> > > > +		ret = reset_control_assert(qmp->nocsr_reset);
> > > > +		if (ret) {
> > > > +			dev_err(qmp->dev, "no-csr reset assert failed\n");
> > > > +			goto err_assert_reset;
> > > > +		}
> > > > -	usleep_range(200, 300);
> > > > +		usleep_range(200, 300);
> > > > +	}
> > > >   	if (!qmp->skip_init) {
> > > >   		ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
> > > > @@ -4641,10 +4647,12 @@ static int qmp_pcie_power_on(struct phy *phy)
> > > >   	if (ret)
> > > >   		return ret;
> > > > -	ret = reset_control_deassert(qmp->nocsr_reset);
> > > > -	if (ret) {
> > > > -		dev_err(qmp->dev, "no-csr reset deassert failed\n");
> > > > -		goto err_disable_pipe_clk;
> > > > +	if (!qmp->skip_reset) {
> > > > +		ret = reset_control_deassert(qmp->nocsr_reset);
> > > > +		if (ret) {
> > > > +			dev_err(qmp->dev, "no-csr reset deassert failed\n");
> > > > +			goto err_disable_pipe_clk;
> > > > +		}
> > > >   	}
> > > >   	if (qmp->skip_init)
> > > > 
> > > > -- 
> > > > 2.34.1
> > > > 
> > > 
> > 
> 
> -- 
> With best wishes
> Dmitry

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



More information about the linux-phy mailing list