phy: rockchip-snps-pcie3: Support rockchip,skip-init

For special scenarios, such as after the PCIe PHY is bifurcation and
with different usage like phy1 is the RC and the other phy0 is the EP.
Since the EP has been initialized in the previous stage, it is not
expected that repeated initialization in the kernel stage will cause
the link to be disconnected. Therefore, no matter which of the two
controllers performs initialization, the PHY re-initialization operation
should be avoided.

Change-Id: I7c04b537b18020d434d14049c5a0661739713265
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
This commit is contained in:
Jon Lin
2025-09-15 18:14:37 +08:00
committed by Tao Huang
parent bc08d6c1b9
commit 0241b8bd2a

View File

@@ -59,6 +59,7 @@ struct rockchip_p3phy_priv {
struct clk_bulk_data *clks;
int num_clks;
bool is_bifurcation;
bool is_initialized;
};
struct rockchip_p3phy_ops {
@@ -215,6 +216,9 @@ static int rockchip_p3phy_init(struct phy *phy)
return ret;
}
if (priv->is_initialized)
return 0;
reset_control_assert(priv->p30phy);
udelay(1);
@@ -233,6 +237,7 @@ static int rockchip_p3phy_exit(struct phy *phy)
clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
reset_control_assert(priv->p30phy);
priv->is_initialized = false;
return 0;
}
@@ -283,33 +288,38 @@ static int rockchip_p3phy_probe(struct platform_device *pdev)
if (IS_ERR(priv->pipe_grf))
dev_info(dev, "failed to find rockchip,pipe_grf regmap\n");
/* Configuring grf with clk enabled. */
ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
if (ret) {
pr_err("failed to enable PCIe bulk clks %d\n", ret);
return ret;
}
priv->is_initialized = device_property_read_bool(dev, "rockchip,skip-init");
ret = device_property_read_u32(dev, "rockchip,pcie30-phymode", &val);
if (!ret) {
priv->pcie30_phymode = val;
if (priv->pcie30_phymode > 4)
priv->pcie30_phymode = PHY_MODE_PCIE_AGGREGATION;
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0,
(0x7<<16) | priv->pcie30_phymode);
} else {
priv->pcie30_phymode = PHY_MODE_PCIE_AGGREGATION;
}
/* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */
if (!IS_ERR(priv->pipe_grf)) {
reg = priv->pcie30_phymode & 3;
if (reg)
regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON,
(reg << 16) | reg);
};
if (!priv->is_initialized) {
ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
if (ret) {
pr_err("failed to enable PCIe bulk clks %d\n", ret);
return ret;
}
clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
if (priv->pcie30_phymode != PHY_MODE_PCIE_AGGREGATION)
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0,
(0x7 << 16) | priv->pcie30_phymode);
/* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */
if (!IS_ERR(priv->pipe_grf)) {
reg = priv->pcie30_phymode & 3;
if (reg)
regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON,
(reg << 16) | reg);
};
clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
}
priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
if (IS_ERR(priv->phy)) {