]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: rzg3s-host: Add PCIe Gen3 (8.0 GT/s) link speed support
authorJohn Madieu <john.madieu.xa@bp.renesas.com>
Fri, 6 Mar 2026 14:34:18 +0000 (15:34 +0100)
committerManivannan Sadhasivam <mani@kernel.org>
Sun, 15 Mar 2026 15:41:49 +0000 (21:11 +0530)
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 <john.madieu.xa@bp.renesas.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> # RZ/V2N EVK
Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://patch.msgid.link/20260306143423.19562-12-john.madieu.xa@bp.renesas.com
drivers/pci/controller/pcie-rzg3s-host.c

index d8a92ad124376d98842f1cedb6199b9385a977d6..182f135fd5e305a9ea418690ba48d8afcdd6b12d 100644 (file)
@@ -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)