From 0241b8bd2a679f5dd6c5ccb6093d5196cf6d0d32 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Mon, 15 Sep 2025 18:14:37 +0800 Subject: [PATCH] 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 --- .../phy/rockchip/phy-rockchip-snps-pcie3.c | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 2933c6fdfb46..57965475cd05 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -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)) {