diff mbox series

[v2,4/5] phy: rockchip: snps-pcie3: Fix bifurcation for RK3588

Message ID 4405be82fdda87ebf9961f95fe3952a624e1f959.1721161722.git.seb-dev@mail.de
State Accepted
Commit ee84a18b3d7fd5aca41f06765fe8027519b2e176
Delegated to: Kever Yang
Headers show
Series phy: rockchip: snps-pcie3: Fix bifurcation and spelling | expand

Commit Message

Sebastian Kropatsch July 16, 2024, 8:42 p.m. UTC
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")
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
---
 .../phy/rockchip/phy-rockchip-snps-pcie3.c    | 24 +++++++------------
 1 file changed, 8 insertions(+), 16 deletions(-)
diff mbox series

Patch

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);