]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
phy: rockchip: snps-pcie3: Fix bifurcation for RK3588
authorSebastian Kropatsch <seb-dev@mail.de>
Sun, 14 Jul 2024 21:23:42 +0000 (23:23 +0200)
committerKever Yang <kever.yang@rock-chips.com>
Wed, 17 Jul 2024 06:48:18 +0000 (14:48 +0800)
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 <seb-dev@mail.de>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
drivers/phy/rockchip/phy-rockchip-snps-pcie3.c

index 1c94875aaaf1cc2d0dba745fc3b6f26da439aac9..fadb77c25cf2a8ac15f5e9794157eab3c1e7b090 100644 (file)
@@ -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);