From ee84a18b3d7fd5aca41f06765fe8027519b2e176 Mon Sep 17 00:00:00 2001 From: Sebastian Kropatsch Date: Sun, 14 Jul 2024 23:23:42 +0200 Subject: [PATCH] phy: rockchip: snps-pcie3: Fix bifurcation for RK3588 Misconfigured `PHP_GRF_PCIESEL` values are causing bifurcation issues, for example on the FriendlyElec CM3588 NAS board which uses bifurcation on both PCIe PCIe ports (all four lanes) to enable four M.2 NVMe sockets. Without this fix, NVMe devices do not get recognized. Correct the `PHP_GRF_PCIESEL` register configuration and simplify the bifurcation logic, enabling proper PCIe bifurcation based on the data-lanes property. This fix is adapted from the upstream Linux commit by Michal Tomek: f8020dfb311d ("phy: rockchip-snps-pcie3: fix bifurcation on rk3588") Fixes: 50e54e80679b ("phy: rockchip: snps-pcie3: Add support for RK3588") Signed-off-by: Sebastian Kropatsch Reviewed-by: Kever Yang --- .../phy/rockchip/phy-rockchip-snps-pcie3.c | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 1c94875aaa..fadb77c25c 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -108,7 +108,7 @@ static int rockchip_p3phy_rk3588_init(struct phy *phy) { struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); u32 reg = 0; - u8 mode = 0; + u8 mode = RK3588_LANE_AGGREGATION; /* Lane aggregation by default */ int ret; /* Deassert PCIe PMA output clamp mode */ @@ -117,28 +117,20 @@ static int rockchip_p3phy_rk3588_init(struct phy *phy) /* Set bifurcation if needed */ for (int i = 0; i < priv->num_lanes; i++) { - if (!priv->lanes[i]) - mode |= (BIT(i) << 3); - if (priv->lanes[i] > 1) - mode |= (BIT(i) >> 1); - } - - if (!mode) { - reg = RK3588_LANE_AGGREGATION; - } else { - if (mode & (BIT(0) | BIT(1))) - reg |= RK3588_BIFURCATION_LANE_0_1; - - if (mode & (BIT(2) | BIT(3))) - reg |= RK3588_BIFURCATION_LANE_2_3; + mode &= ~RK3588_LANE_AGGREGATION; + if (priv->lanes[i] == 3) + mode |= RK3588_BIFURCATION_LANE_0_1; + if (priv->lanes[i] == 4) + mode |= RK3588_BIFURCATION_LANE_2_3; } + reg = mode; regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, (0x7 << 16) | reg); /* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */ - reg = (mode & (BIT(6) | BIT(7))) >> 6; + reg = mode & 3; if (reg) regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, (reg << 16) | reg); -- 2.39.5