Skip to content

Commit

Permalink
phy: rockchip-snps-pcie3: fix bifurcation on rk3588
Browse files Browse the repository at this point in the history
So far all RK3588 boards use fully aggregated PCIe. CM3588 is one
of the few boards using this feature and apparently it is broken.

The PHY offers the following mapping options:

  port 0 lane 0 - always mapped to controller 0 (4L)
  port 0 lane 1 - to controller 0 or 2 (1L0)
  port 1 lane 0 - to controller 0 or 1 (2L)
  port 1 lane 1 - to controller 0, 1 or 3 (1L1)

The data-lanes DT property maps these as follows:

  0 = no controller (unsupported by the HW)
  1 = 4L
  2 = 2L
  3 = 1L0
  4 = 1L1

That allows the following configurations with first column being the
mainline data-lane mapping, second column being the downstream name,
third column being PCIE3PHY_GRF_CMN_CON0 and PHP_GRF_PCIESEL register
values and final column being the user visible lane setup:

  <1 1 1 1> = AGGREG = [4 0] = x4 (aggregation)
  <1 1 2 2> = NANBNB = [0 0] = x2 x2 (no bif.)
  <1 3 2 2> = NANBBI = [1 1] = x2 x1x1 (bif. of port 0)
  <1 1 2 4> = NABINB = [2 2] = x1x1 x2 (bif. of port 1)
  <1 3 2 4> = NABIBI = [3 3] = x1x1 x1x1 (bif. of both ports)

The driver currently does not program PHP_GRF_PCIESEL correctly, which
is fixed by this patch. As a side-effect the new logic is much simpler
than the old logic.

Fixes: 2e9bffc ("phy: rockchip: Support PCIe v3")
Signed-off-by: Michal Tomek <mtdev79b@gmail.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20240404-rk3588-pcie-bifurcation-fixes-v1-1-9907136eeafd@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
  • Loading branch information
Michal Tomek authored and Vinod Koul committed Apr 6, 2024
1 parent 3a16101 commit f8020df
Showing 1 changed file with 8 additions and 16 deletions.
24 changes: 8 additions & 16 deletions drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,36 +132,28 @@ static const struct rockchip_p3phy_ops rk3568_ops = {
static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv)
{
u32 reg = 0;
u8 mode = 0;
u8 mode = RK3588_LANE_AGGREGATION; /* default */
int ret;

/* Deassert PCIe PMA output clamp mode */
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24));

/* 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 */
if (!IS_ERR(priv->pipe_grf)) {
reg = (mode & (BIT(6) | BIT(7))) >> 6;
reg = mode & 3;
if (reg)
regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON,
(reg << 16) | reg);
Expand Down

0 comments on commit f8020df

Please sign in to comment.