ls = readw_relaxed(host->pcie + pcie_cap + PCI_EXP_LNKSTA);
cs2 = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2);
- switch (pcie_get_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]) {
++ switch (pcie_get_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;