From: John Madieu Date: Fri, 6 Mar 2026 14:34:18 +0000 (+0100) Subject: PCI: rzg3s-host: Add PCIe Gen3 (8.0 GT/s) link speed support X-Git-Tag: v7.1-rc1~151^2~1^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5e9a5af5c9a2797a5e41e8ee565ce8108588f956;p=thirdparty%2Fkernel%2Flinux.git PCI: rzg3s-host: Add PCIe Gen3 (8.0 GT/s) link speed support Extend the link speed configuration to support Gen3 (8.0 GT/s) in addition to Gen2 (5.0 GT/s). This is required for RZ/G3E PCIe host support, which is Gen3 capable. Instead of relying on DT max-link-speed for configuration, read the hardware capabilities from the PCI_EXP_LNKCAP register to determine the maximum supported speed. The DT max-link-speed property is now only used as an optional limit when explicitly specified, which aligns with PCIe subsystem expectations. Signed-off-by: John Madieu Signed-off-by: Manivannan Sadhasivam Tested-by: Lad Prabhakar # RZ/V2N EVK Tested-by: Claudiu Beznea Reviewed-by: Claudiu Beznea Link: https://patch.msgid.link/20260306143423.19562-12-john.madieu.xa@bp.renesas.com --- diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c index d8a92ad124376..182f135fd5e30 100644 --- a/drivers/pci/controller/pcie-rzg3s-host.c +++ b/drivers/pci/controller/pcie-rzg3s-host.c @@ -1004,8 +1004,9 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host) { u32 remote_supported_link_speeds, max_supported_link_speeds; u32 cs2, tmp, pcie_cap = RZG3S_PCI_CFG_PCIEC; - u32 cur_link_speed, link_speed; + u32 cur_link_speed, link_speed, hw_max_speed; u8 ltssm_state_l0 = 0xc; + u32 lnkcap; int ret; u16 ls; @@ -1025,7 +1026,22 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host) ls = readw_relaxed(host->pcie + pcie_cap + PCI_EXP_LNKSTA); cs2 = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2); - switch (pcie_link_speed[host->max_link_speed]) { + /* Read hardware supported link speed from Link Capabilities Register */ + lnkcap = readl_relaxed(host->pcie + pcie_cap + PCI_EXP_LNKCAP); + hw_max_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, lnkcap); + + /* + * Use DT max-link-speed only as a limit. If specified and lower + * than hardware capability, cap to that value. + */ + if (host->max_link_speed > 0 && host->max_link_speed < hw_max_speed) + hw_max_speed = host->max_link_speed; + + switch (pcie_link_speed[hw_max_speed]) { + case PCIE_SPEED_8_0GT: + max_supported_link_speeds = GENMASK(PCI_EXP_LNKSTA_CLS_8_0GB - 1, 0); + link_speed = PCI_EXP_LNKCTL2_TLS_8_0GT; + break; case PCIE_SPEED_5_0GT: max_supported_link_speeds = GENMASK(PCI_EXP_LNKSTA_CLS_5_0GB - 1, 0); link_speed = PCI_EXP_LNKCTL2_TLS_5_0GT; @@ -1041,10 +1057,10 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host) remote_supported_link_speeds &= max_supported_link_speeds; /* - * Return if max link speed is already set or the connected device + * Return if target link speed is already set or the connected device * doesn't support it. */ - if (cur_link_speed == host->max_link_speed || + if (cur_link_speed == hw_max_speed || remote_supported_link_speeds != max_supported_link_speeds) return 0; @@ -1632,8 +1648,6 @@ static int rzg3s_pcie_probe(struct platform_device *pdev) host->pcie = host->axi + RZG3S_PCI_CFG_BASE; host->max_link_speed = of_pci_get_max_link_speed(np); - if (host->max_link_speed < 0) - host->max_link_speed = 2; ret = rzg3s_pcie_host_parse_port(host); if (ret)