[PATCH v2 0/7] rockchip: rk3568: Fix use of PCIe bifurcation

This series add support for use of PCIe bifurcation on RK3568, and as a bonus support for the RK3588 PHY is also included. With PCIe bifurcation supported it is possible to enable PCIe on more RK3568 boards, e.g. on NanoPi R5C and NanoPi R5S. This series only include fixing the mini PCIe slot on Radxa E25.
Most parts of this series was imported almost 1:1 from mainline linux.
Patch 1 fixes configuration of number of lanes in pcie_dw_rockchip. Patch 2-3 refactor the snps-pcie3 phy driver. Patch 4 add bifurcation support for RK3568. Patch 5 add support for RK3588 to snps-pcie3 driver. Patch 6 fixes use of pcie2x1l0 on ROCK 5B. Patch 7 enables the mini PCIe slot on Radxa E25.
Changes in v2: - Fix use of signal from comb PHY on RK3588 - Add fixes tag
The RK3588 PHY part was tested on a ROCK 5B together with device tree files picked from Sebastian Reichel's rk3588 branch at [1].
Patches in this series is also aviliable at [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/tree/?h=r... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-pcie-bifurcation-v2
Jonas Karlman (7): pci: pcie_dw_rockchip: Configure number of lanes and link width speed phy: rockchip: snps-pcie3: Refactor to use clk_bulk API phy: rockchip: snps-pcie3: Refactor to use a phy_init ops phy: rockchip: snps-pcie3: Add bifurcation support for RK3568 phy: rockchip: snps-pcie3: Add support for RK3588 phy: rockchip: naneng-combphy: Use signal from comb PHY on RK3588 rockchip: rk3568-radxa-e25: Enable pcie3x1 node
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +- configs/radxa-e25-rk3568_defconfig | 1 - drivers/pci/pcie_dw_rockchip.c | 58 ++++- .../rockchip/phy-rockchip-naneng-combphy.c | 6 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 230 ++++++++++++++---- 5 files changed, 241 insertions(+), 65 deletions(-)

Change to use clk_bulk API and syscon_regmap_lookup_by_phandle to simplify in preparation for upcoming support of a RK3588 variant.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - No change
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 58 +++---------------- 1 file changed, 9 insertions(+), 49 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 66c75f98e6d1..3053543a3329 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -26,17 +26,13 @@ * @mmio: The base address of PHY internal registers * @phy_grf: The regmap for controlling pipe signal * @p30phy: The reset signal for PHY - * @ref_clk_m: The reference clock of M for PHY - * @ref_clk_n: The reference clock of N for PHY - * @pclk: The clock for accessing PHY blocks + * @clks: The clocks for PHY */ struct rockchip_p3phy_priv { void __iomem *mmio; struct regmap *phy_grf; struct reset_ctl p30phy; - struct clk ref_clk_m; - struct clk ref_clk_n; - struct clk pclk; + struct clk_bulk clks; };
static int rochchip_p3phy_init(struct phy *phy) @@ -44,18 +40,10 @@ static int rochchip_p3phy_init(struct phy *phy) struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); int ret;
- ret = clk_enable(&priv->ref_clk_m); - if (ret < 0 && ret != -ENOSYS) + ret = clk_enable_bulk(&priv->clks); + if (ret) return ret;
- ret = clk_enable(&priv->ref_clk_n); - if (ret < 0 && ret != -ENOSYS) - goto err_ref; - - ret = clk_enable(&priv->pclk); - if (ret < 0 && ret != -ENOSYS) - goto err_pclk; - reset_assert(&priv->p30phy); udelay(1);
@@ -67,21 +55,13 @@ static int rochchip_p3phy_init(struct phy *phy) udelay(1);
return 0; -err_pclk: - clk_disable(&priv->ref_clk_n); -err_ref: - clk_disable(&priv->ref_clk_m); - - return ret; }
static int rochchip_p3phy_exit(struct phy *phy) { struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev);
- clk_disable(&priv->ref_clk_m); - clk_disable(&priv->ref_clk_n); - clk_disable(&priv->pclk); + clk_disable_bulk(&priv->clks); reset_assert(&priv->p30phy);
return 0; @@ -90,21 +70,13 @@ static int rochchip_p3phy_exit(struct phy *phy) static int rockchip_p3phy_probe(struct udevice *dev) { struct rockchip_p3phy_priv *priv = dev_get_priv(dev); - struct udevice *syscon; int ret;
priv->mmio = dev_read_addr_ptr(dev); if (!priv->mmio) return -EINVAL;
- ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, - "rockchip,phy-grf", &syscon); - if (ret) { - pr_err("unable to find syscon device for rockchip,phy-grf\n"); - return ret; - } - - priv->phy_grf = syscon_get_regmap(syscon); + priv->phy_grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,phy-grf"); if (IS_ERR(priv->phy_grf)) { dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); return PTR_ERR(priv->phy_grf); @@ -116,22 +88,10 @@ static int rockchip_p3phy_probe(struct udevice *dev) return ret; }
- ret = clk_get_by_name(dev, "refclk_m", &priv->ref_clk_m); + ret = clk_get_bulk(dev, &priv->clks); if (ret) { - dev_err(dev, "failed to find ref clock M\n"); - return PTR_ERR(&priv->ref_clk_m); - } - - ret = clk_get_by_name(dev, "refclk_n", &priv->ref_clk_n); - if (ret) { - dev_err(dev, "failed to find ref clock N\n"); - return PTR_ERR(&priv->ref_clk_n); - } - - ret = clk_get_by_name(dev, "pclk", &priv->pclk); - if (ret) { - dev_err(dev, "failed to find pclk\n"); - return PTR_ERR(&priv->pclk); + dev_err(dev, "failed to get clocks\n"); + return ret; }
return 0;

On 2023/8/3 03:04, Jonas Karlman wrote:
Change to use clk_bulk API and syscon_regmap_lookup_by_phandle to simplify in preparation for upcoming support of a RK3588 variant.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
No change
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 58 +++---------------- 1 file changed, 9 insertions(+), 49 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 66c75f98e6d1..3053543a3329 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -26,17 +26,13 @@
- @mmio: The base address of PHY internal registers
- @phy_grf: The regmap for controlling pipe signal
- @p30phy: The reset signal for PHY
- @ref_clk_m: The reference clock of M for PHY
- @ref_clk_n: The reference clock of N for PHY
- @pclk: The clock for accessing PHY blocks
*/ struct rockchip_p3phy_priv { void __iomem *mmio; struct regmap *phy_grf; struct reset_ctl p30phy;
- @clks: The clocks for PHY
- struct clk ref_clk_m;
- struct clk ref_clk_n;
- struct clk pclk;
struct clk_bulk clks; };
static int rochchip_p3phy_init(struct phy *phy)
@@ -44,18 +40,10 @@ static int rochchip_p3phy_init(struct phy *phy) struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); int ret;
- ret = clk_enable(&priv->ref_clk_m);
- if (ret < 0 && ret != -ENOSYS)
- ret = clk_enable_bulk(&priv->clks);
- if (ret) return ret;
- ret = clk_enable(&priv->ref_clk_n);
- if (ret < 0 && ret != -ENOSYS)
goto err_ref;
- ret = clk_enable(&priv->pclk);
- if (ret < 0 && ret != -ENOSYS)
goto err_pclk;
- reset_assert(&priv->p30phy); udelay(1);
@@ -67,21 +55,13 @@ static int rochchip_p3phy_init(struct phy *phy) udelay(1);
return 0; -err_pclk:
- clk_disable(&priv->ref_clk_n);
-err_ref:
clk_disable(&priv->ref_clk_m);
return ret; }
static int rochchip_p3phy_exit(struct phy *phy) { struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev);
clk_disable(&priv->ref_clk_m);
clk_disable(&priv->ref_clk_n);
clk_disable(&priv->pclk);
clk_disable_bulk(&priv->clks); reset_assert(&priv->p30phy);
return 0;
@@ -90,21 +70,13 @@ static int rochchip_p3phy_exit(struct phy *phy) static int rockchip_p3phy_probe(struct udevice *dev) { struct rockchip_p3phy_priv *priv = dev_get_priv(dev);
struct udevice *syscon; int ret;
priv->mmio = dev_read_addr_ptr(dev); if (!priv->mmio) return -EINVAL;
ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
"rockchip,phy-grf", &syscon);
if (ret) {
pr_err("unable to find syscon device for rockchip,phy-grf\n");
return ret;
}
priv->phy_grf = syscon_get_regmap(syscon);
- priv->phy_grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,phy-grf"); if (IS_ERR(priv->phy_grf)) { dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); return PTR_ERR(priv->phy_grf);
@@ -116,22 +88,10 @@ static int rockchip_p3phy_probe(struct udevice *dev) return ret; }
- ret = clk_get_by_name(dev, "refclk_m", &priv->ref_clk_m);
- ret = clk_get_bulk(dev, &priv->clks); if (ret) {
dev_err(dev, "failed to find ref clock M\n");
return PTR_ERR(&priv->ref_clk_m);
- }
- ret = clk_get_by_name(dev, "refclk_n", &priv->ref_clk_n);
- if (ret) {
dev_err(dev, "failed to find ref clock N\n");
return PTR_ERR(&priv->ref_clk_n);
- }
- ret = clk_get_by_name(dev, "pclk", &priv->pclk);
- if (ret) {
dev_err(dev, "failed to find pclk\n");
return PTR_ERR(&priv->pclk);
dev_err(dev, "failed to get clocks\n");
return ret;
}
return 0;

Add a phy_init ops in preparation for upcoming support of a RK3588 variant in the driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - No change
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 3053543a3329..b76b5386bef0 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -35,8 +35,32 @@ struct rockchip_p3phy_priv { struct clk_bulk clks; };
+struct rockchip_p3phy_ops { + int (*phy_init)(struct phy *phy); +}; + +static int rockchip_p3phy_rk3568_init(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); + + /* Deassert PCIe PMA output clamp mode */ + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, + (0x1 << 15) | (0x1 << 31)); + + reset_deassert(&priv->p30phy); + udelay(1); + + return 0; +} + +static const struct rockchip_p3phy_ops rk3568_ops = { + .phy_init = rockchip_p3phy_rk3568_init, +}; + static int rochchip_p3phy_init(struct phy *phy) { + struct rockchip_p3phy_ops *ops = + (struct rockchip_p3phy_ops *)dev_get_driver_data(phy->dev); struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); int ret;
@@ -47,14 +71,11 @@ static int rochchip_p3phy_init(struct phy *phy) reset_assert(&priv->p30phy); udelay(1);
- /* Deassert PCIe PMA output clamp mode */ - regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, - (0x1 << 15) | (0x1 << 31)); - - reset_deassert(&priv->p30phy); - udelay(1); + ret = ops->phy_init(phy); + if (ret) + clk_disable_bulk(&priv->clks);
- return 0; + return ret; }
static int rochchip_p3phy_exit(struct phy *phy) @@ -103,7 +124,10 @@ static struct phy_ops rochchip_p3phy_ops = { };
static const struct udevice_id rockchip_p3phy_of_match[] = { - { .compatible = "rockchip,rk3568-pcie3-phy" }, + { + .compatible = "rockchip,rk3568-pcie3-phy", + .data = (ulong)&rk3568_ops, + }, { }, };

On 2023/8/3 03:04, Jonas Karlman wrote:
Add a phy_init ops in preparation for upcoming support of a RK3588 variant in the driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
No change
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 3053543a3329..b76b5386bef0 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -35,8 +35,32 @@ struct rockchip_p3phy_priv { struct clk_bulk clks; };
+struct rockchip_p3phy_ops {
- int (*phy_init)(struct phy *phy);
+};
+static int rockchip_p3phy_rk3568_init(struct phy *phy) +{
- struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev);
- /* Deassert PCIe PMA output clamp mode */
- regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9,
(0x1 << 15) | (0x1 << 31));
- reset_deassert(&priv->p30phy);
- udelay(1);
- return 0;
+}
+static const struct rockchip_p3phy_ops rk3568_ops = {
- .phy_init = rockchip_p3phy_rk3568_init,
+};
- static int rochchip_p3phy_init(struct phy *phy) {
- struct rockchip_p3phy_ops *ops =
struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); int ret;(struct rockchip_p3phy_ops *)dev_get_driver_data(phy->dev);
@@ -47,14 +71,11 @@ static int rochchip_p3phy_init(struct phy *phy) reset_assert(&priv->p30phy); udelay(1);
- /* Deassert PCIe PMA output clamp mode */
- regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9,
(0x1 << 15) | (0x1 << 31));
- reset_deassert(&priv->p30phy);
- udelay(1);
- ret = ops->phy_init(phy);
- if (ret)
clk_disable_bulk(&priv->clks);
- return 0;
return ret; }
static int rochchip_p3phy_exit(struct phy *phy)
@@ -103,7 +124,10 @@ static struct phy_ops rochchip_p3phy_ops = { };
static const struct udevice_id rockchip_p3phy_of_match[] = {
- { .compatible = "rockchip,rk3568-pcie3-phy" },
- {
.compatible = "rockchip,rk3568-pcie3-phy",
.data = (ulong)&rk3568_ops,
- }, { }, };

Add support for the RK3588 variant to the driver.
Code imported almost 1:1 from mainline linux driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - No change
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 642819b1f672..a4392daf4c92 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -27,6 +27,17 @@
#define RK3568_BIFURCATION_LANE_0_1 BIT(0)
+/* Register for RK3588 */ +#define PHP_GRF_PCIESEL_CON 0x100 +#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 +#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 +#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 +#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0)) + +#define RK3588_BIFURCATION_LANE_0_1 BIT(0) +#define RK3588_BIFURCATION_LANE_2_3 BIT(1) +#define RK3588_LANE_AGGREGATION BIT(2) + /** * struct rockchip_p3phy_priv - RK DW PCIe PHY state * @@ -40,6 +51,7 @@ struct rockchip_p3phy_priv { void __iomem *mmio; struct regmap *phy_grf; + struct regmap *pipe_grf; struct reset_ctl p30phy; struct clk_bulk clks; int num_lanes; @@ -93,6 +105,66 @@ static const struct rockchip_p3phy_ops rk3568_ops = { .phy_init = rockchip_p3phy_rk3568_init, };
+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; + 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; + } + + 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; + if (reg) + regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, + (reg << 16) | reg); + + reset_deassert(&priv->p30phy); + udelay(1); + + ret = regmap_read_poll_timeout(priv->phy_grf, + RK3588_PCIE3PHY_GRF_PHY0_STATUS1, + reg, RK3588_SRAM_INIT_DONE(reg), + 0, 500); + ret |= regmap_read_poll_timeout(priv->phy_grf, + RK3588_PCIE3PHY_GRF_PHY1_STATUS1, + reg, RK3588_SRAM_INIT_DONE(reg), + 0, 500); + if (ret) + dev_err(phy->dev, "lock failed 0x%x\n", reg); + + return ret; +} + +static const struct rockchip_p3phy_ops rk3588_ops = { + .phy_init = rockchip_p3phy_rk3588_init, +}; + static int rochchip_p3phy_init(struct phy *phy) { struct rockchip_p3phy_ops *ops = @@ -139,6 +211,15 @@ static int rockchip_p3phy_probe(struct udevice *dev) return PTR_ERR(priv->phy_grf); }
+ if (device_is_compatible(dev, "rockchip,rk3588-pcie3-phy")) { + priv->pipe_grf = + syscon_regmap_lookup_by_phandle(dev, "rockchip,pipe-grf"); + if (IS_ERR(priv->pipe_grf)) { + dev_err(dev, "failed to find rockchip,pipe_grf regmap\n"); + return PTR_ERR(priv->pipe_grf); + } + } + ret = dev_read_size(dev, "data-lanes"); if (ret > 0) { priv->num_lanes = ret / sizeof(u32); @@ -181,6 +262,10 @@ static const struct udevice_id rockchip_p3phy_of_match[] = { .compatible = "rockchip,rk3568-pcie3-phy", .data = (ulong)&rk3568_ops, }, + { + .compatible = "rockchip,rk3588-pcie3-phy", + .data = (ulong)&rk3588_ops, + }, { }, };

On 2023/8/3 03:04, Jonas Karlman wrote:
Add support for the RK3588 variant to the driver.
Code imported almost 1:1 from mainline linux driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
No change
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 642819b1f672..a4392daf4c92 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -27,6 +27,17 @@
#define RK3568_BIFURCATION_LANE_0_1 BIT(0)
+/* Register for RK3588 */ +#define PHP_GRF_PCIESEL_CON 0x100 +#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 +#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 +#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 +#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0))
+#define RK3588_BIFURCATION_LANE_0_1 BIT(0) +#define RK3588_BIFURCATION_LANE_2_3 BIT(1) +#define RK3588_LANE_AGGREGATION BIT(2)
- /**
- struct rockchip_p3phy_priv - RK DW PCIe PHY state
@@ -40,6 +51,7 @@ struct rockchip_p3phy_priv { void __iomem *mmio; struct regmap *phy_grf;
- struct regmap *pipe_grf; struct reset_ctl p30phy; struct clk_bulk clks; int num_lanes;
@@ -93,6 +105,66 @@ static const struct rockchip_p3phy_ops rk3568_ops = { .phy_init = rockchip_p3phy_rk3568_init, };
+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;
- 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;
- }
- 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;
- if (reg)
regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON,
(reg << 16) | reg);
- reset_deassert(&priv->p30phy);
- udelay(1);
- ret = regmap_read_poll_timeout(priv->phy_grf,
RK3588_PCIE3PHY_GRF_PHY0_STATUS1,
reg, RK3588_SRAM_INIT_DONE(reg),
0, 500);
- ret |= regmap_read_poll_timeout(priv->phy_grf,
RK3588_PCIE3PHY_GRF_PHY1_STATUS1,
reg, RK3588_SRAM_INIT_DONE(reg),
0, 500);
- if (ret)
dev_err(phy->dev, "lock failed 0x%x\n", reg);
- return ret;
+}
+static const struct rockchip_p3phy_ops rk3588_ops = {
- .phy_init = rockchip_p3phy_rk3588_init,
+};
- static int rochchip_p3phy_init(struct phy *phy) { struct rockchip_p3phy_ops *ops =
@@ -139,6 +211,15 @@ static int rockchip_p3phy_probe(struct udevice *dev) return PTR_ERR(priv->phy_grf); }
- if (device_is_compatible(dev, "rockchip,rk3588-pcie3-phy")) {
priv->pipe_grf =
syscon_regmap_lookup_by_phandle(dev, "rockchip,pipe-grf");
if (IS_ERR(priv->pipe_grf)) {
dev_err(dev, "failed to find rockchip,pipe_grf regmap\n");
return PTR_ERR(priv->pipe_grf);
}
- }
- ret = dev_read_size(dev, "data-lanes"); if (ret > 0) { priv->num_lanes = ret / sizeof(u32);
@@ -181,6 +262,10 @@ static const struct udevice_id rockchip_p3phy_of_match[] = { .compatible = "rockchip,rk3568-pcie3-phy", .data = (ulong)&rk3568_ops, },
- {
.compatible = "rockchip,rk3588-pcie3-phy",
.data = (ulong)&rk3588_ops,
- }, { }, };

Set number of lanes and link width speed control register based on the num-lanes property.
Code imported almost 1:1 from dw_pcie_setup in mainline linux.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - No change
drivers/pci/pcie_dw_rockchip.c | 58 +++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c index 1a35fae5c3a8..bc4635f67136 100644 --- a/drivers/pci/pcie_dw_rockchip.c +++ b/drivers/pci/pcie_dw_rockchip.c @@ -18,6 +18,7 @@ #include <asm/io.h> #include <asm-generic/gpio.h> #include <dm/device_compat.h> +#include <linux/bitfield.h> #include <linux/iopoll.h> #include <linux/delay.h> #include <power/regulator.h> @@ -43,6 +44,7 @@ struct rk_pcie { struct reset_ctl_bulk rsts; struct gpio_desc rst_gpio; u32 gen; + u32 num_lanes; };
/* Parameters for the waiting for iATU enabled routine */ @@ -152,12 +154,13 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg, * rk_pcie_configure() - Configure link capabilities and speed * * @rk_pcie: Pointer to the PCI controller state - * @cap_speed: The capabilities and speed to configure * * Configure the link capabilities and speed in the PCIe root complex. */ -static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed) +static void rk_pcie_configure(struct rk_pcie *pci) { + u32 val; + dw_pcie_dbi_write_enable(&pci->dw, true);
/* Disable BAR 0 and BAR 1 */ @@ -167,11 +170,49 @@ static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed) PCI_BASE_ADDRESS_1);
clrsetbits_le32(pci->dw.dbi_base + PCIE_LINK_CAPABILITY, - TARGET_LINK_SPEED_MASK, cap_speed); + TARGET_LINK_SPEED_MASK, pci->gen);
clrsetbits_le32(pci->dw.dbi_base + PCIE_LINK_CTL_2, - TARGET_LINK_SPEED_MASK, cap_speed); + TARGET_LINK_SPEED_MASK, pci->gen); + + /* Set the number of lanes */ + val = readl(pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL); + val &= ~PORT_LINK_FAST_LINK_MODE; + val |= PORT_LINK_DLL_LINK_EN; + val &= ~PORT_LINK_MODE_MASK; + switch (pci->num_lanes) { + case 1: + val |= PORT_LINK_MODE_1_LANES; + break; + case 2: + val |= PORT_LINK_MODE_2_LANES; + break; + case 4: + val |= PORT_LINK_MODE_4_LANES; + break; + default: + dev_err(pci->dw.dev, "num-lanes %u: invalid value\n", pci->num_lanes); + goto out; + } + writel(val, pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL); + + /* Set link width speed control register */ + val = readl(pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + val &= ~PORT_LOGIC_LINK_WIDTH_MASK; + switch (pci->num_lanes) { + case 1: + val |= PORT_LOGIC_LINK_WIDTH_1_LANES; + break; + case 2: + val |= PORT_LOGIC_LINK_WIDTH_2_LANES; + break; + case 4: + val |= PORT_LOGIC_LINK_WIDTH_4_LANES; + break; + } + writel(val, pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+out: dw_pcie_dbi_write_enable(&pci->dw, false); }
@@ -231,11 +272,10 @@ static int is_link_up(struct rk_pcie *priv) * rk_pcie_link_up() - Wait for the link to come up * * @rk_pcie: Pointer to the PCI controller state - * @cap_speed: Desired link speed * * Return: 1 (true) for active line and negetive (false) for no link (timeout) */ -static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed) +static int rk_pcie_link_up(struct rk_pcie *priv) { int retries;
@@ -245,7 +285,7 @@ static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed) }
/* DW pre link configurations */ - rk_pcie_configure(priv, cap_speed); + rk_pcie_configure(priv);
rk_pcie_disable_ltssm(priv); rk_pcie_link_status_clear(priv); @@ -341,7 +381,7 @@ static int rockchip_pcie_init_port(struct udevice *dev) rk_pcie_writel_apb(priv, 0x0, 0xf00040); pcie_dw_setup_host(&priv->dw);
- ret = rk_pcie_link_up(priv, priv->gen); + ret = rk_pcie_link_up(priv); if (ret < 0) goto err_link_up;
@@ -419,6 +459,8 @@ static int rockchip_pcie_parse_dt(struct udevice *dev) priv->gen = dev_read_u32_default(dev, "max-link-speed", LINK_SPEED_GEN_3);
+ priv->num_lanes = dev_read_u32_default(dev, "num-lanes", 1); + return 0;
rockchip_pcie_parse_dt_err_phy_get_by_index:

On 2023/8/3 03:04, Jonas Karlman wrote:
Set number of lanes and link width speed control register based on the num-lanes property.
Code imported almost 1:1 from dw_pcie_setup in mainline linux.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
No change
drivers/pci/pcie_dw_rockchip.c | 58 +++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c index 1a35fae5c3a8..bc4635f67136 100644 --- a/drivers/pci/pcie_dw_rockchip.c +++ b/drivers/pci/pcie_dw_rockchip.c @@ -18,6 +18,7 @@ #include <asm/io.h> #include <asm-generic/gpio.h> #include <dm/device_compat.h> +#include <linux/bitfield.h> #include <linux/iopoll.h> #include <linux/delay.h> #include <power/regulator.h> @@ -43,6 +44,7 @@ struct rk_pcie { struct reset_ctl_bulk rsts; struct gpio_desc rst_gpio; u32 gen;
u32 num_lanes; };
/* Parameters for the waiting for iATU enabled routine */
@@ -152,12 +154,13 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg,
- rk_pcie_configure() - Configure link capabilities and speed
- @rk_pcie: Pointer to the PCI controller state
*/
- @cap_speed: The capabilities and speed to configure
- Configure the link capabilities and speed in the PCIe root complex.
-static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed) +static void rk_pcie_configure(struct rk_pcie *pci) {
u32 val;
dw_pcie_dbi_write_enable(&pci->dw, true);
/* Disable BAR 0 and BAR 1 */
@@ -167,11 +170,49 @@ static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed) PCI_BASE_ADDRESS_1);
clrsetbits_le32(pci->dw.dbi_base + PCIE_LINK_CAPABILITY,
TARGET_LINK_SPEED_MASK, cap_speed);
TARGET_LINK_SPEED_MASK, pci->gen);
clrsetbits_le32(pci->dw.dbi_base + PCIE_LINK_CTL_2,
TARGET_LINK_SPEED_MASK, cap_speed);
TARGET_LINK_SPEED_MASK, pci->gen);
- /* Set the number of lanes */
- val = readl(pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
- val &= ~PORT_LINK_FAST_LINK_MODE;
- val |= PORT_LINK_DLL_LINK_EN;
- val &= ~PORT_LINK_MODE_MASK;
- switch (pci->num_lanes) {
- case 1:
val |= PORT_LINK_MODE_1_LANES;
break;
- case 2:
val |= PORT_LINK_MODE_2_LANES;
break;
- case 4:
val |= PORT_LINK_MODE_4_LANES;
break;
- default:
dev_err(pci->dw.dev, "num-lanes %u: invalid value\n", pci->num_lanes);
goto out;
- }
- writel(val, pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
- /* Set link width speed control register */
- val = readl(pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
- val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
- switch (pci->num_lanes) {
- case 1:
val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
break;
- case 2:
val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
break;
- case 4:
val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
break;
- }
- writel(val, pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+out: dw_pcie_dbi_write_enable(&pci->dw, false); }
@@ -231,11 +272,10 @@ static int is_link_up(struct rk_pcie *priv)
- rk_pcie_link_up() - Wait for the link to come up
- @rk_pcie: Pointer to the PCI controller state
*/
- @cap_speed: Desired link speed
- Return: 1 (true) for active line and negetive (false) for no link (timeout)
-static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed) +static int rk_pcie_link_up(struct rk_pcie *priv) { int retries;
@@ -245,7 +285,7 @@ static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed) }
/* DW pre link configurations */
- rk_pcie_configure(priv, cap_speed);
rk_pcie_configure(priv);
rk_pcie_disable_ltssm(priv); rk_pcie_link_status_clear(priv);
@@ -341,7 +381,7 @@ static int rockchip_pcie_init_port(struct udevice *dev) rk_pcie_writel_apb(priv, 0x0, 0xf00040); pcie_dw_setup_host(&priv->dw);
- ret = rk_pcie_link_up(priv, priv->gen);
- ret = rk_pcie_link_up(priv); if (ret < 0) goto err_link_up;
@@ -419,6 +459,8 @@ static int rockchip_pcie_parse_dt(struct udevice *dev) priv->gen = dev_read_u32_default(dev, "max-link-speed", LINK_SPEED_GEN_3);
priv->num_lanes = dev_read_u32_default(dev, "num-lanes", 1);
return 0;
rockchip_pcie_parse_dt_err_phy_get_by_index:

Configure aggregation or bifurcation mode on RK3568 based on the value of data-lanes property.
Code imported almost 1:1 from mainline linux driver.
Fixes: 6ec62b6ca698 ("phy: rockchip: Add Rockchip Synopsys PCIe 3.0 PHY") Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - Add fixes tag
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index b76b5386bef0..642819b1f672 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -16,9 +16,16 @@ #include <dm/device_compat.h> #include <dm/lists.h>
-#define GRF_PCIE30PHY_CON1 0x4 -#define GRF_PCIE30PHY_CON6 0x18 -#define GRF_PCIE30PHY_CON9 0x24 +/* Register for RK3568 */ +#define GRF_PCIE30PHY_CON1 0x4 +#define GRF_PCIE30PHY_CON6 0x18 +#define GRF_PCIE30PHY_CON9 0x24 +#define GRF_PCIE30PHY_DA_OCM (BIT(15) | BIT(31)) +#define GRF_PCIE30PHY_STATUS0 0x80 +#define GRF_PCIE30PHY_WR_EN (0xf << 16) +#define SRAM_INIT_DONE(reg) (reg & BIT(14)) + +#define RK3568_BIFURCATION_LANE_0_1 BIT(0)
/** * struct rockchip_p3phy_priv - RK DW PCIe PHY state @@ -27,12 +34,16 @@ * @phy_grf: The regmap for controlling pipe signal * @p30phy: The reset signal for PHY * @clks: The clocks for PHY + * @num_lanes: The number of lane to controller mappings + * @lanes: The lane to controller mapping */ struct rockchip_p3phy_priv { void __iomem *mmio; struct regmap *phy_grf; struct reset_ctl p30phy; struct clk_bulk clks; + int num_lanes; + u32 lanes[4]; };
struct rockchip_p3phy_ops { @@ -42,15 +53,40 @@ struct rockchip_p3phy_ops { static int rockchip_p3phy_rk3568_init(struct phy *phy) { struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); + bool bifurcation = false; + int ret; + u32 reg;
/* Deassert PCIe PMA output clamp mode */ - regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, - (0x1 << 15) | (0x1 << 31)); + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, GRF_PCIE30PHY_DA_OCM); + + for (int i = 0; i < priv->num_lanes; i++) { + if (priv->lanes[i] > 1) + bifurcation = true; + } + + /* Set bifurcation if needed, and it doesn't care RC/EP */ + if (bifurcation) { + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, + GRF_PCIE30PHY_WR_EN | RK3568_BIFURCATION_LANE_0_1); + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON1, + GRF_PCIE30PHY_DA_OCM); + } else { + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, + GRF_PCIE30PHY_WR_EN & ~RK3568_BIFURCATION_LANE_0_1); + }
reset_deassert(&priv->p30phy); udelay(1);
- return 0; + ret = regmap_read_poll_timeout(priv->phy_grf, + GRF_PCIE30PHY_STATUS0, + reg, SRAM_INIT_DONE(reg), + 0, 500); + if (ret) + dev_err(phy->dev, "lock failed 0x%x\n", reg); + + return ret; }
static const struct rockchip_p3phy_ops rk3568_ops = { @@ -103,6 +139,23 @@ static int rockchip_p3phy_probe(struct udevice *dev) return PTR_ERR(priv->phy_grf); }
+ ret = dev_read_size(dev, "data-lanes"); + if (ret > 0) { + priv->num_lanes = ret / sizeof(u32); + if (priv->num_lanes < 2 || + priv->num_lanes > ARRAY_SIZE(priv->lanes)) { + dev_err(dev, "unsupported data-lanes property size\n"); + return -EINVAL; + } + + ret = dev_read_u32_array(dev, "data-lanes", priv->lanes, + priv->num_lanes); + if (ret) { + dev_err(dev, "failed to read data-lanes property\n"); + return ret; + } + } + ret = reset_get_by_name(dev, "phy", &priv->p30phy); if (ret) { dev_err(dev, "no phy reset control specified\n");

On 2023/8/3 03:04, Jonas Karlman wrote:
Configure aggregation or bifurcation mode on RK3568 based on the value of data-lanes property.
Code imported almost 1:1 from mainline linux driver.
Fixes: 6ec62b6ca698 ("phy: rockchip: Add Rockchip Synopsys PCIe 3.0 PHY") Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
Add fixes tag
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index b76b5386bef0..642819b1f672 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -16,9 +16,16 @@ #include <dm/device_compat.h> #include <dm/lists.h>
-#define GRF_PCIE30PHY_CON1 0x4 -#define GRF_PCIE30PHY_CON6 0x18 -#define GRF_PCIE30PHY_CON9 0x24 +/* Register for RK3568 */ +#define GRF_PCIE30PHY_CON1 0x4 +#define GRF_PCIE30PHY_CON6 0x18 +#define GRF_PCIE30PHY_CON9 0x24 +#define GRF_PCIE30PHY_DA_OCM (BIT(15) | BIT(31)) +#define GRF_PCIE30PHY_STATUS0 0x80 +#define GRF_PCIE30PHY_WR_EN (0xf << 16) +#define SRAM_INIT_DONE(reg) (reg & BIT(14))
+#define RK3568_BIFURCATION_LANE_0_1 BIT(0)
/**
- struct rockchip_p3phy_priv - RK DW PCIe PHY state
@@ -27,12 +34,16 @@
- @phy_grf: The regmap for controlling pipe signal
- @p30phy: The reset signal for PHY
- @clks: The clocks for PHY
- @num_lanes: The number of lane to controller mappings
- @lanes: The lane to controller mapping
*/ struct rockchip_p3phy_priv { void __iomem *mmio; struct regmap *phy_grf; struct reset_ctl p30phy; struct clk_bulk clks;
int num_lanes;
u32 lanes[4]; };
struct rockchip_p3phy_ops {
@@ -42,15 +53,40 @@ struct rockchip_p3phy_ops { static int rockchip_p3phy_rk3568_init(struct phy *phy) { struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev);
bool bifurcation = false;
int ret;
u32 reg;
/* Deassert PCIe PMA output clamp mode */
- regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9,
(0x1 << 15) | (0x1 << 31));
regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, GRF_PCIE30PHY_DA_OCM);
for (int i = 0; i < priv->num_lanes; i++) {
if (priv->lanes[i] > 1)
bifurcation = true;
}
/* Set bifurcation if needed, and it doesn't care RC/EP */
if (bifurcation) {
regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6,
GRF_PCIE30PHY_WR_EN | RK3568_BIFURCATION_LANE_0_1);
regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON1,
GRF_PCIE30PHY_DA_OCM);
} else {
regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6,
GRF_PCIE30PHY_WR_EN & ~RK3568_BIFURCATION_LANE_0_1);
}
reset_deassert(&priv->p30phy); udelay(1);
- return 0;
ret = regmap_read_poll_timeout(priv->phy_grf,
GRF_PCIE30PHY_STATUS0,
reg, SRAM_INIT_DONE(reg),
0, 500);
if (ret)
dev_err(phy->dev, "lock failed 0x%x\n", reg);
return ret; }
static const struct rockchip_p3phy_ops rk3568_ops = {
@@ -103,6 +139,23 @@ static int rockchip_p3phy_probe(struct udevice *dev) return PTR_ERR(priv->phy_grf); }
- ret = dev_read_size(dev, "data-lanes");
- if (ret > 0) {
priv->num_lanes = ret / sizeof(u32);
if (priv->num_lanes < 2 ||
priv->num_lanes > ARRAY_SIZE(priv->lanes)) {
dev_err(dev, "unsupported data-lanes property size\n");
return -EINVAL;
}
ret = dev_read_u32_array(dev, "data-lanes", priv->lanes,
priv->num_lanes);
if (ret) {
dev_err(dev, "failed to read data-lanes property\n");
return ret;
}
- }
- ret = reset_get_by_name(dev, "phy", &priv->p30phy); if (ret) { dev_err(dev, "no phy reset control specified\n");

Enable mini PCIe slot, pcie3x1 node, now that the PCIe PHY driver support bifurcation.
A pinctrl is assigned for reset-gpios or the device may freeze running pci enum and nothing is connected to the mini PCIe slot.
Also drop the AHCI_PCI Kconfig option as this option is not required for a functional M.2 SATA drive slot.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - No change
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +++++++++-- configs/radxa-e25-rk3568_defconfig | 1 - 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi b/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi index 572bdc5665b1..1136f0bb3b81 100644 --- a/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi +++ b/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi @@ -8,9 +8,16 @@ }; };
-/* PCIe PHY driver in U-Boot does not support bifurcation */ &pcie3x1 { - status = "disabled"; + pinctrl-0 = <&pcie30x1_reset_h>; +}; + +&pinctrl { + pcie { + pcie30x1_reset_h: pcie30x1-reset-h { + rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; };
&sdhci { diff --git a/configs/radxa-e25-rk3568_defconfig b/configs/radxa-e25-rk3568_defconfig index a905100a794d..2dfff6af3bd1 100644 --- a/configs/radxa-e25-rk3568_defconfig +++ b/configs/radxa-e25-rk3568_defconfig @@ -54,7 +54,6 @@ CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigne CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y -CONFIG_AHCI_PCI=y CONFIG_DWC_AHCI=y CONFIG_SPL_CLK=y CONFIG_ROCKCHIP_GPIO=y

On 2023/8/3 03:04, Jonas Karlman wrote:
Enable mini PCIe slot, pcie3x1 node, now that the PCIe PHY driver support bifurcation.
A pinctrl is assigned for reset-gpios or the device may freeze running pci enum and nothing is connected to the mini PCIe slot.
Also drop the AHCI_PCI Kconfig option as this option is not required for a functional M.2 SATA drive slot.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
No change
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +++++++++-- configs/radxa-e25-rk3568_defconfig | 1 - 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi b/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi index 572bdc5665b1..1136f0bb3b81 100644 --- a/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi +++ b/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi @@ -8,9 +8,16 @@ }; };
-/* PCIe PHY driver in U-Boot does not support bifurcation */ &pcie3x1 {
- status = "disabled";
- pinctrl-0 = <&pcie30x1_reset_h>;
+};
+&pinctrl {
pcie {
pcie30x1_reset_h: pcie30x1-reset-h {
rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
};
}; };
&sdhci {
diff --git a/configs/radxa-e25-rk3568_defconfig b/configs/radxa-e25-rk3568_defconfig index a905100a794d..2dfff6af3bd1 100644 --- a/configs/radxa-e25-rk3568_defconfig +++ b/configs/radxa-e25-rk3568_defconfig @@ -54,7 +54,6 @@ CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigne CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y -CONFIG_AHCI_PCI=y CONFIG_DWC_AHCI=y CONFIG_SPL_CLK=y CONFIG_ROCKCHIP_GPIO=y

Route signal from comb PHY instead of PCIe3 PHY to PCIe1l0 and PCIe1l1.
Fixes use of pcie2x1l0 on ROCK 5B.
Code imported from mainline linux driver.
Fixes: c5b4a012bca8 ("phy: rockchip: naneng-combphy: Support rk3588") Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - New patch
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index d5408ccac976..9ca66bf8db92 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -61,6 +61,8 @@ struct rockchip_combphy_grfcfg { struct combphy_reg pipe_con1_for_sata; struct combphy_reg pipe_sgmii_mac_sel; struct combphy_reg pipe_xpcs_phy_ready; + struct combphy_reg pipe_pcie1l0_sel; + struct combphy_reg pipe_pcie1l1_sel; struct combphy_reg u3otg0_port_en; struct combphy_reg u3otg1_port_en; }; @@ -435,6 +437,8 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) param_write(priv->phy_grf, &cfg->con1_for_pcie, true); param_write(priv->phy_grf, &cfg->con2_for_pcie, true); param_write(priv->phy_grf, &cfg->con3_for_pcie, true); + param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true); + param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true); break; case PHY_TYPE_USB3: param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); @@ -507,6 +511,8 @@ static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = { /* pipe-grf */ .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 }, + .pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 }, + .pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 }, };
static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {

On 2023/8/3 03:04, Jonas Karlman wrote:
Route signal from comb PHY instead of PCIe3 PHY to PCIe1l0 and PCIe1l1.
Fixes use of pcie2x1l0 on ROCK 5B.
Code imported from mainline linux driver.
Fixes: c5b4a012bca8 ("phy: rockchip: naneng-combphy: Support rk3588") Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
New patch
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index d5408ccac976..9ca66bf8db92 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -61,6 +61,8 @@ struct rockchip_combphy_grfcfg { struct combphy_reg pipe_con1_for_sata; struct combphy_reg pipe_sgmii_mac_sel; struct combphy_reg pipe_xpcs_phy_ready;
- struct combphy_reg pipe_pcie1l0_sel;
- struct combphy_reg pipe_pcie1l1_sel; struct combphy_reg u3otg0_port_en; struct combphy_reg u3otg1_port_en; };
@@ -435,6 +437,8 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) param_write(priv->phy_grf, &cfg->con1_for_pcie, true); param_write(priv->phy_grf, &cfg->con2_for_pcie, true); param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true);
break; case PHY_TYPE_USB3: param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true);
@@ -507,6 +511,8 @@ static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = { /* pipe-grf */ .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 },
.pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 },
.pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 }, };
static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {

hi,
On 8/3/23 04:22, Jonas Karlman wrote:
This series add support for use of PCIe bifurcation on RK3568, and as a bonus support for the RK3588 PHY is also included. With PCIe bifurcation supported it is possible to enable PCIe on more RK3568 boards, e.g. on NanoPi R5C and NanoPi R5S. This series only include fixing the mini PCIe slot on Radxa E25.
Most parts of this series was imported almost 1:1 from mainline linux.
Patch 1 fixes configuration of number of lanes in pcie_dw_rockchip. Patch 2-3 refactor the snps-pcie3 phy driver. Patch 4 add bifurcation support for RK3568. Patch 5 add support for RK3588 to snps-pcie3 driver. Patch 6 fixes use of pcie2x1l0 on ROCK 5B. Patch 7 enables the mini PCIe slot on Radxa E25.
Changes in v2:
- Fix use of signal from comb PHY on RK3588
- Add fixes tag
The RK3588 PHY part was tested on a ROCK 5B together with device tree files picked from Sebastian Reichel's rk3588 branch at [1].
Patches in this series is also aviliable at [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/tree/?h=r... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-pcie-bifurcation-v2
Jonas Karlman (7): pci: pcie_dw_rockchip: Configure number of lanes and link width speed phy: rockchip: snps-pcie3: Refactor to use clk_bulk API phy: rockchip: snps-pcie3: Refactor to use a phy_init ops phy: rockchip: snps-pcie3: Add bifurcation support for RK3568 phy: rockchip: snps-pcie3: Add support for RK3588 phy: rockchip: naneng-combphy: Use signal from comb PHY on RK3588 rockchip: rk3568-radxa-e25: Enable pcie3x1 node
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +- configs/radxa-e25-rk3568_defconfig | 1 - drivers/pci/pcie_dw_rockchip.c | 58 ++++- .../rockchip/phy-rockchip-naneng-combphy.c | 6 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 230 ++++++++++++++---- 5 files changed, 241 insertions(+), 65 deletions(-)
for the whole series,
Tested-by: FUKAUMI Naoki naoki@radxa.com
on ROCK 5B with NVMe and linux-next 20230802 device tree.

1) Tested rk3568 NanpPi-R5s with Samsung 980 NVMe using linux 6.4.7 device tree. MMC boot media.
2) Tested rk3588 ROCK 5B with Samsung 980 and Samsung 970 EVO Plus NVMe using Sebastian Reichel's rk3588 device tree: https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/log/?h=rk... Both MMC and SPI boot media were tested.
Tested-by: John Clark inindev@gmail.com
On 8/3/23 2:29 AM, FUKAUMI Naoki wrote:
hi,
On 8/3/23 04:22, Jonas Karlman wrote:
This series add support for use of PCIe bifurcation on RK3568, and as a bonus support for the RK3588 PHY is also included. With PCIe bifurcation supported it is possible to enable PCIe on more RK3568 boards, e.g. on NanoPi R5C and NanoPi R5S. This series only include fixing the mini PCIe slot on Radxa E25.
Most parts of this series was imported almost 1:1 from mainline linux.
Patch 1 fixes configuration of number of lanes in pcie_dw_rockchip. Patch 2-3 refactor the snps-pcie3 phy driver. Patch 4 add bifurcation support for RK3568. Patch 5 add support for RK3588 to snps-pcie3 driver. Patch 6 fixes use of pcie2x1l0 on ROCK 5B. Patch 7 enables the mini PCIe slot on Radxa E25.
Changes in v2:
- Fix use of signal from comb PHY on RK3588
- Add fixes tag
The RK3588 PHY part was tested on a ROCK 5B together with device tree files picked from Sebastian Reichel's rk3588 branch at [1].
Patches in this series is also aviliable at [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/tree/?h=r... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-pcie-bifurcation-v2
Jonas Karlman (7): pci: pcie_dw_rockchip: Configure number of lanes and link width speed phy: rockchip: snps-pcie3: Refactor to use clk_bulk API phy: rockchip: snps-pcie3: Refactor to use a phy_init ops phy: rockchip: snps-pcie3: Add bifurcation support for RK3568 phy: rockchip: snps-pcie3: Add support for RK3588 phy: rockchip: naneng-combphy: Use signal from comb PHY on RK3588 rockchip: rk3568-radxa-e25: Enable pcie3x1 node
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +- configs/radxa-e25-rk3568_defconfig | 1 - drivers/pci/pcie_dw_rockchip.c | 58 ++++- .../rockchip/phy-rockchip-naneng-combphy.c | 6 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 230 ++++++++++++++---- 5 files changed, 241 insertions(+), 65 deletions(-)
for the whole series,
Tested-by: FUKAUMI Naoki naoki@radxa.com
on ROCK 5B with NVMe and linux-next 20230802 device tree.

Hi Kever,
It would be nice to get some feedback and plans for this and the following series :-)
rockchip: rk3568: Fix use of PCIe bifurcation (this series) https://patchwork.ozlabs.org/cover/1816140/
rockchip: rk3568-nanopi-r5: Add missing PCIe options https://patchwork.ozlabs.org/cover/1816147/
rockchip: Port IO-domain driver for RK3568 from linux https://patchwork.ozlabs.org/cover/1823769/
I also plan to send a v2 with small update based on the little feedback I got on the following:
rockchip: Add GMAC support for RK3568 and RK3588 https://patchwork.ozlabs.org/cover/1817469/
Regards, Jonas
On 2023-08-02 21:04, Jonas Karlman wrote:
This series add support for use of PCIe bifurcation on RK3568, and as a bonus support for the RK3588 PHY is also included. With PCIe bifurcation supported it is possible to enable PCIe on more RK3568 boards, e.g. on NanoPi R5C and NanoPi R5S. This series only include fixing the mini PCIe slot on Radxa E25.
Most parts of this series was imported almost 1:1 from mainline linux.
Patch 1 fixes configuration of number of lanes in pcie_dw_rockchip. Patch 2-3 refactor the snps-pcie3 phy driver. Patch 4 add bifurcation support for RK3568. Patch 5 add support for RK3588 to snps-pcie3 driver. Patch 6 fixes use of pcie2x1l0 on ROCK 5B. Patch 7 enables the mini PCIe slot on Radxa E25.
Changes in v2:
- Fix use of signal from comb PHY on RK3588
- Add fixes tag
The RK3588 PHY part was tested on a ROCK 5B together with device tree files picked from Sebastian Reichel's rk3588 branch at [1].
Patches in this series is also aviliable at [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/tree/?h=r... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-pcie-bifurcation-v2
Jonas Karlman (7): pci: pcie_dw_rockchip: Configure number of lanes and link width speed phy: rockchip: snps-pcie3: Refactor to use clk_bulk API phy: rockchip: snps-pcie3: Refactor to use a phy_init ops phy: rockchip: snps-pcie3: Add bifurcation support for RK3568 phy: rockchip: snps-pcie3: Add support for RK3588 phy: rockchip: naneng-combphy: Use signal from comb PHY on RK3588 rockchip: rk3568-radxa-e25: Enable pcie3x1 node
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +- configs/radxa-e25-rk3568_defconfig | 1 - drivers/pci/pcie_dw_rockchip.c | 58 ++++- .../rockchip/phy-rockchip-naneng-combphy.c | 6 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 230 ++++++++++++++---- 5 files changed, 241 insertions(+), 65 deletions(-)

Hi Jonas,
Basically these patches are feature update and should be merge and send in next MW.
I have question about PCIe bifurcation, does this also merged in linux kernel? I do check the status
in kernel mailing list but forget to feedback with you, I didn't see the pcie node in rk3588 dtsi.
I have a little bit confuse about how the phy init for different controller:
eg: if the hardware use pcie3 phy as 2lane + 1 lane + 1 lane, how to write pcie/phy dts?
Thanks,
- Kever
On 2023/9/26 05:30, Jonas Karlman wrote:
Hi Kever,
It would be nice to get some feedback and plans for this and the following series :-)
rockchip: rk3568: Fix use of PCIe bifurcation (this series) https://patchwork.ozlabs.org/cover/1816140/
rockchip: rk3568-nanopi-r5: Add missing PCIe options https://patchwork.ozlabs.org/cover/1816147/
rockchip: Port IO-domain driver for RK3568 from linux https://patchwork.ozlabs.org/cover/1823769/
I also plan to send a v2 with small update based on the little feedback I got on the following:
rockchip: Add GMAC support for RK3568 and RK3588 https://patchwork.ozlabs.org/cover/1817469/
Regards, Jonas
On 2023-08-02 21:04, Jonas Karlman wrote:
This series add support for use of PCIe bifurcation on RK3568, and as a bonus support for the RK3588 PHY is also included. With PCIe bifurcation supported it is possible to enable PCIe on more RK3568 boards, e.g. on NanoPi R5C and NanoPi R5S. This series only include fixing the mini PCIe slot on Radxa E25.
Most parts of this series was imported almost 1:1 from mainline linux.
Patch 1 fixes configuration of number of lanes in pcie_dw_rockchip. Patch 2-3 refactor the snps-pcie3 phy driver. Patch 4 add bifurcation support for RK3568. Patch 5 add support for RK3588 to snps-pcie3 driver. Patch 6 fixes use of pcie2x1l0 on ROCK 5B. Patch 7 enables the mini PCIe slot on Radxa E25.
Changes in v2:
- Fix use of signal from comb PHY on RK3588
- Add fixes tag
The RK3588 PHY part was tested on a ROCK 5B together with device tree files picked from Sebastian Reichel's rk3588 branch at [1].
Patches in this series is also aviliable at [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/tree/?h=r... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-pcie-bifurcation-v2
Jonas Karlman (7): pci: pcie_dw_rockchip: Configure number of lanes and link width speed phy: rockchip: snps-pcie3: Refactor to use clk_bulk API phy: rockchip: snps-pcie3: Refactor to use a phy_init ops phy: rockchip: snps-pcie3: Add bifurcation support for RK3568 phy: rockchip: snps-pcie3: Add support for RK3588 phy: rockchip: naneng-combphy: Use signal from comb PHY on RK3588 rockchip: rk3568-radxa-e25: Enable pcie3x1 node
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +- configs/radxa-e25-rk3568_defconfig | 1 - drivers/pci/pcie_dw_rockchip.c | 58 ++++- .../rockchip/phy-rockchip-naneng-combphy.c | 6 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 230 ++++++++++++++---- 5 files changed, 241 insertions(+), 65 deletions(-)

Hi Kever,
On 2023-09-27 03:57, Kever Yang wrote:
Hi Jonas,
Basically these patches are feature update and should be merge and send in next MW.
Great and thanks!
I have question about PCIe bifurcation, does this also merged in linux kernel? I do check the status
in kernel mailing list but forget to feedback with you, I didn't see the pcie node in rk3588 dtsi.
The snps-pcie3 phy driver should match what has been merged into mainline linux. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv...
RK3588 DT nodes for PCIe2 and PCIe3 was merged for linux v6.6-rc1 in:
arm64: dts: rockchip: add PCIe3 support for rk3588 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/ar...
arm64: dts: rockchip: add rk3588 PCIe2 support https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/ar...
And following two pending series add PCIe nodes to EVB1 and Rock 5B.
RK3588 EVB1 PCIe support https://lore.kernel.org/all/20230918141327.131108-1-sebastian.reichel@collab...
RK3588 Rock 5B PCIe support https://lore.kernel.org/all/20230918141451.131247-1-sebastian.reichel@collab...
This series was tested together with a device tree that should be very close to what was merged for v6.6-rc1 and above Rock 5B PCIe nodes. https://github.com/Kwiboo/u-boot-rockchip/commit/d040547bad665f7c6ea9e83c55e...
Following patch should sync latest rk3588 dtsi and add pcie nodes. https://patchwork.ozlabs.org/project/uboot/patch/20230905114736.22585-1-naok...
I expect that there may be a need for one more DT sync after all this have landed in next/master.
I have a little bit confuse about how the phy init for different controller:
eg: if the hardware use pcie3 phy as 2lane + 1 lane + 1 lane, how to write pcie/phy dts?
This is an example from rk3568-radxa-e25.dts
&pcie30phy { /* First data-lane is routed to controller 1 * Second data-lane is routed to controller 2 */ data-lanes = <1 2>; ... };
&pcie3x1 { /* Use 1 data-lane */ num-lanes = <1>; ... };
&pcie3x2 { /* Use 1 data-lane */ num-lanes = <1>; ... };
Above works with this series in U-Boot and also in mainline linux. Not sure the RK3588 bifurcation part of driver have been verified on real HW, rk3588 boards available for testing have typicality not used bifurcation.
For 2 lane + 1 lane + 1 lane I would expect DT to look something like:
&pcie3-phy { data-lanes = <1 1 2 3>; };
&pcie3-1 { num-lanes = <2>; };
&pcie3-2 { num-lanes = <1>; };
&pcie3-3 { num-lanes = <1>; };
See bindings for data-lanes property: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Docu...
Regards, Jonas
Thanks,
- Kever
On 2023/9/26 05:30, Jonas Karlman wrote:
Hi Kever,
It would be nice to get some feedback and plans for this and the following series :-)
rockchip: rk3568: Fix use of PCIe bifurcation (this series) https://patchwork.ozlabs.org/cover/1816140/
rockchip: rk3568-nanopi-r5: Add missing PCIe options https://patchwork.ozlabs.org/cover/1816147/
rockchip: Port IO-domain driver for RK3568 from linux https://patchwork.ozlabs.org/cover/1823769/
I also plan to send a v2 with small update based on the little feedback I got on the following:
rockchip: Add GMAC support for RK3568 and RK3588 https://patchwork.ozlabs.org/cover/1817469/
Regards, Jonas
On 2023-08-02 21:04, Jonas Karlman wrote:
This series add support for use of PCIe bifurcation on RK3568, and as a bonus support for the RK3588 PHY is also included. With PCIe bifurcation supported it is possible to enable PCIe on more RK3568 boards, e.g. on NanoPi R5C and NanoPi R5S. This series only include fixing the mini PCIe slot on Radxa E25.
Most parts of this series was imported almost 1:1 from mainline linux.
Patch 1 fixes configuration of number of lanes in pcie_dw_rockchip. Patch 2-3 refactor the snps-pcie3 phy driver. Patch 4 add bifurcation support for RK3568. Patch 5 add support for RK3588 to snps-pcie3 driver. Patch 6 fixes use of pcie2x1l0 on ROCK 5B. Patch 7 enables the mini PCIe slot on Radxa E25.
Changes in v2:
- Fix use of signal from comb PHY on RK3588
- Add fixes tag
The RK3588 PHY part was tested on a ROCK 5B together with device tree files picked from Sebastian Reichel's rk3588 branch at [1].
Patches in this series is also aviliable at [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/tree/?h=r... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-pcie-bifurcation-v2
Jonas Karlman (7): pci: pcie_dw_rockchip: Configure number of lanes and link width speed phy: rockchip: snps-pcie3: Refactor to use clk_bulk API phy: rockchip: snps-pcie3: Refactor to use a phy_init ops phy: rockchip: snps-pcie3: Add bifurcation support for RK3568 phy: rockchip: snps-pcie3: Add support for RK3588 phy: rockchip: naneng-combphy: Use signal from comb PHY on RK3588 rockchip: rk3568-radxa-e25: Enable pcie3x1 node
arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi | 11 +- configs/radxa-e25-rk3568_defconfig | 1 - drivers/pci/pcie_dw_rockchip.c | 58 ++++- .../rockchip/phy-rockchip-naneng-combphy.c | 6 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 230 ++++++++++++++---- 5 files changed, 241 insertions(+), 65 deletions(-)

Hi,
On Wed, Sep 27, 2023 at 06:07:59PM +0000, Jonas Karlman wrote:
Above works with this series in U-Boot and also in mainline linux. Not sure the RK3588 bifurcation part of driver have been verified on real HW, rk3588 boards available for testing have typicality not used bifurcation.
Upstream kernel bifurcation code looks ok to me. It's quite different from Rockchip vendor implementation, which might have confused Kever. I also missed this when having a quick look initially. As you said Rock 5A, Rock 5B and EVB1 do not use bifurcation, so no testing happened on our side.
Greetings,
-- Sebastian

Hi,
Gesendet: Sonntag, 01. Oktober 2023 um 21:11 Uhr Von: "Sebastian Reichel" sebastian.reichel@collabora.com An: "Jonas Karlman" jonas@kwiboo.se Cc: "Kever Yang" kever.yang@rock-chips.com, "Simon Glass" sjg@chromium.org, "Philipp Tomsich" philipp.tomsich@vrull.eu, "Eugen Hristev" eugen.hristev@collabora.com, "Jon Lin" jon.lin@rock-chips.com, "FUKAUMI Naoki" naoki@radxa.com, "John Clark" inindev@gmail.com, u-boot@lists.denx.de Betreff: Re: [PATCH v2 0/7] rockchip: rk3568: Fix use of PCIe bifurcation
Hi,
On Wed, Sep 27, 2023 at 06:07:59PM +0000, Jonas Karlman wrote:
Above works with this series in U-Boot and also in mainline linux. Not sure the RK3588 bifurcation part of driver have been verified on real HW, rk3588 boards available for testing have typicality not used bifurcation.
Upstream kernel bifurcation code looks ok to me. It's quite different from Rockchip vendor implementation, which might have confused Kever. I also missed this when having a quick look initially. As you said Rock 5A, Rock 5B and EVB1 do not use bifurcation, so no testing happened on our side.
my Bananapi R2Pro (rk3568) uses bifurcation and it is working in mainline Linux, but not yet in uboot.
posted my test-results here: https://patchwork.ozlabs.org/project/uboot/patch/20230918173624.31464-1-linu...
regards Frank

Hi Frank,
On 2023-10-02 09:17, Frank Wunderlich wrote:
Hi,
Gesendet: Sonntag, 01. Oktober 2023 um 21:11 Uhr Von: "Sebastian Reichel" sebastian.reichel@collabora.com An: "Jonas Karlman" jonas@kwiboo.se Cc: "Kever Yang" kever.yang@rock-chips.com, "Simon Glass" sjg@chromium.org, "Philipp Tomsich" philipp.tomsich@vrull.eu, "Eugen Hristev" eugen.hristev@collabora.com, "Jon Lin" jon.lin@rock-chips.com, "FUKAUMI Naoki" naoki@radxa.com, "John Clark" inindev@gmail.com, u-boot@lists.denx.de Betreff: Re: [PATCH v2 0/7] rockchip: rk3568: Fix use of PCIe bifurcation
Hi,
On Wed, Sep 27, 2023 at 06:07:59PM +0000, Jonas Karlman wrote:
Above works with this series in U-Boot and also in mainline linux. Not sure the RK3588 bifurcation part of driver have been verified on real HW, rk3588 boards available for testing have typicality not used bifurcation.
Upstream kernel bifurcation code looks ok to me. It's quite different from Rockchip vendor implementation, which might have confused Kever. I also missed this when having a quick look initially. As you said Rock 5A, Rock 5B and EVB1 do not use bifurcation, so no testing happened on our side.
my Bananapi R2Pro (rk3568) uses bifurcation and it is working in mainline Linux, but not yet in uboot.
The issue on your Bananapi R2Pro is most likely not related to the pcie bifurcation code added in this series.
The coded added in this series works same/very similar as on mainline linux and fixes bifurcation use on devices such as Radxa E25 and NanoPi R5C/R5S.
Please clarify if pcie work in mainline linux when booting with mainline u-boot, or does it only work when booting with vendor u-boot? (in case vendor u-boot set different/default pinconf).
posted my test-results here: https://patchwork.ozlabs.org/project/uboot/patch/20230918173624.31464-1-linu...
From your pci enum command I only see an expected pcie@fe270000 (ngff)
link fail. Does it also print out link fail for pcie@fe280000 (minipcie)?
If not, try running "pci 1" and "pci 2" after an initial "pci enum" to see if the root complex and your minipcie device is detected.
Regards, Jonas
regards Frank

Hi Jonas,
Gesendet: Montag, 02. Oktober 2023 um 10:33 Uhr Von: "Jonas Karlman" jonas@kwiboo.se An: "Frank Wunderlich" frank-w@public-files.de, "Sebastian Reichel" sebastian.reichel@collabora.com Cc: "Kever Yang" kever.yang@rock-chips.com, "Simon Glass" sjg@chromium.org, "Philipp Tomsich" philipp.tomsich@vrull.eu, "Eugen Hristev" eugen.hristev@collabora.com, "Jon Lin" jon.lin@rock-chips.com, "FUKAUMI Naoki" naoki@radxa.com, "John Clark" inindev@gmail.com, u-boot@lists.denx.de Betreff: Re: Aw: Re: [PATCH v2 0/7] rockchip: rk3568: Fix use of PCIe bifurcation
Hi Frank,
On 2023-10-02 09:17, Frank Wunderlich wrote:
Hi,
Gesendet: Sonntag, 01. Oktober 2023 um 21:11 Uhr Von: "Sebastian Reichel" sebastian.reichel@collabora.com An: "Jonas Karlman" jonas@kwiboo.se Cc: "Kever Yang" kever.yang@rock-chips.com, "Simon Glass" sjg@chromium.org, "Philipp Tomsich" philipp.tomsich@vrull.eu, "Eugen Hristev" eugen.hristev@collabora.com, "Jon Lin" jon.lin@rock-chips.com, "FUKAUMI Naoki" naoki@radxa.com, "John Clark" inindev@gmail.com, u-boot@lists.denx.de Betreff: Re: [PATCH v2 0/7] rockchip: rk3568: Fix use of PCIe bifurcation
Hi,
On Wed, Sep 27, 2023 at 06:07:59PM +0000, Jonas Karlman wrote:
Above works with this series in U-Boot and also in mainline linux. Not sure the RK3588 bifurcation part of driver have been verified on real HW, rk3588 boards available for testing have typicality not used bifurcation.
Upstream kernel bifurcation code looks ok to me. It's quite different from Rockchip vendor implementation, which might have confused Kever. I also missed this when having a quick look initially. As you said Rock 5A, Rock 5B and EVB1 do not use bifurcation, so no testing happened on our side.
my Bananapi R2Pro (rk3568) uses bifurcation and it is working in mainline Linux, but not yet in uboot.
The issue on your Bananapi R2Pro is most likely not related to the pcie bifurcation code added in this series.
The coded added in this series works same/very similar as on mainline linux and fixes bifurcation use on devices such as Radxa E25 and NanoPi R5C/R5S.
Please clarify if pcie work in mainline linux when booting with mainline u-boot, or does it only work when booting with vendor u-boot? (in case vendor u-boot set different/default pinconf).
posted my test-results here: https://patchwork.ozlabs.org/project/uboot/patch/20230918173624.31464-1-linu...
From your pci enum command I only see an expected pcie@fe270000 (ngff) link fail. Does it also print out link fail for pcie@fe280000 (minipcie)?
good catch, you're right, no message of mpcie, only ngff (no card)
#initial status (before enabling pcie-related regulators) BPI-R2PRO> regulator status Name Enabled uV mA Mode Status vdd_logic enabled 900000 - - 0 vdd_gpu enabled 900000 - - 0 vcc_ddr enabled 500000 - - 0 vdd_npu disabled 500000 - - 0 vcc_1v8 enabled 1800000 - - 0 vdda0v9_image enabled 900000 - - 0 vdda_0v9 enabled 900000 - - 0 vdda0v9_pmu enabled 900000 - - 0 vccio_acodec enabled 3300000 - - 0 vccio_sd enabled 3300000 - - 0 vcc3v3_pmu enabled 3300000 - - 0 vcca_1v8 enabled 1800000 - - 0 vcca1v8_pmu enabled 1800000 - - 0 vcca1v8_image enabled 1800000 - - 0 vcc_3v3 enabled 0 - - 0 vcc3v3_sd enabled 0 - - 0 dc_12v enabled 12000000 - - 0 vcc3v3_sys enabled 3300000 - - 0 vcc5v0_sys enabled 5000000 - - 0 pcie30_avdd0v9 enabled 900000 - - 0 pcie30_avdd1v8 enabled 1800000 - - 0 vcc3v3_pcie disabled 3300000 - - 0 vcc3v3_minipcie disabled 3300000 - - 0 vcc3v3_ngff disabled 3300000 - - 0 vcc5v0_usb enabled 5000000 - - 0 vcc5v0_usb_host disabled 5000000 - - 0 vcc5v0_usb_otg disabled 5000000 - - 0 BPI-R2PRO> regulator dev vcc3v3_pcie dev: vcc3v3_pcie @ vcc3v3-pi6c-05-regulator BPI-R2PRO> regulator enable BPI-R2PRO> regulator status Regulator vcc3v3_pcie status: * enable: 1 (true) * value uV: 3300000 * current uA: No data available (err: -61) * mode id: Function not implemented (err: -38) BPI-R2PRO> regulator dev vcc3v3_minipcie dev: vcc3v3_minipcie @ vcc3v3-minipcie-regulator BPI-R2PRO> regulator status Regulator vcc3v3_minipcie status: * enable: 0 (false) * value uV: 3300000 * current uA: No data available (err: -61) * mode id: Function not implemented (err: -38) BPI-R2PRO> regulator enable BPI-R2PRO> regulator status Regulator vcc3v3_minipcie status: * enable: 1 (true) * value uV: 3300000 * current uA: No data available (err: -61) * mode id: Function not implemented (err: -38)
BPI-R2PRO> pci enum pcie_dw_rockchip pcie@fe270000: PCIe-0 Link Fail BPI-R2PRO> pci 1 Scanning PCI devices on bus 1 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 01.00.00 0x1d87 0x3566 Bridge device 0x04 BPI-R2PRO> pci 2 Scanning PCI devices on bus 2 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 02.00.00 0x14c3 0x7612 Network controller 0x80
so mpcie slot works so far as it detects the network-card (mt7612), only need to find a way to enable the regulators (vcc3v3_pcie, vcc3v3_minipcie, vcc3v3_ngff).
btw. is there a way to show overall status (like the first regulator status) after enabling the regulators (only shows current regulator)?
If not, try running "pci 1" and "pci 2" after an initial "pci enum" to see if the root complex and your minipcie device is detected.
sorry for confusion, have not done much with pcie in uboot yet. so you can add my tested by
Tested-by: Frank Wunderlich frank-w@public-files.de
Thank you very much for your work.
regards Frank
participants (6)
-
Frank Wunderlich
-
FUKAUMI Naoki
-
John Clark
-
Jonas Karlman
-
Kever Yang
-
Sebastian Reichel