]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdgpu: fix nbif 6.3.1 l1 low power not functional
authorYang Wang <kevinyang.wang@amd.com>
Mon, 10 Aug 2026 04:48:19 +0000 (12:48 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 12 Aug 2026 14:22:53 +0000 (10:22 -0400)
The PCIe L1 low‑power settings for NBIF 6.3.1 were never applied due to
unresolved register mapping, which caused the relevant code to be compiled out.
As a result, the PCIe link could not enter L1/L23 power‑down states or transition to L0s.

Properly configure the link control register to enable L1 and L23 power‑down,
and permit L0s link transitions. Keep LTR disabled and let the PCI core enable it
only after verifying end‑to‑end root complex support across switches.

Fixes: 894c6d3522d1 ("drm/amdgpu: Add nbif v6_3_1 ip block support")
Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Kenneth Feng <Kenneth.feng@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c2417f9fd7049d5a8d87eefd82fd6e36ba1ff7b6)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c

index 000516b5845a3b9dfe360d7975b41ba73da56442..61eb0513dc97db02e29c9af1646cafc2bb6c5d79 100644 (file)
@@ -500,7 +500,6 @@ static u32 nbif_v6_3_1_get_rom_offset(struct amdgpu_device *adev)
 static void nbif_v6_3_1_program_ltr(struct amdgpu_device *adev)
 {
        uint32_t def, data;
-       u16 devctl2;
 
        def = RREG32_SOC15(NBIO, 0, regRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL);
        data = 0x35EB;
@@ -514,15 +513,8 @@ static void nbif_v6_3_1_program_ltr(struct amdgpu_device *adev)
        if (def != data)
                WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP2, data);
 
-       pcie_capability_read_word(adev->pdev, PCI_EXP_DEVCTL2, &devctl2);
-
-       if (adev->pdev->ltr_path == (devctl2 & PCI_EXP_DEVCTL2_LTR_EN))
-               return;
-
-       if (adev->pdev->ltr_path)
-               pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_LTR_EN);
-       else
-               pcie_capability_clear_word(adev->pdev, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_LTR_EN);
+       pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2,
+                                PCI_EXP_DEVCTL2_LTR_EN);
 }
 #endif
 
@@ -530,7 +522,7 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
 {
 #ifdef CONFIG_PCIEASPM
        uint32_t def, data;
-       u16 devctl2, ltr;
+       u16 ltr;
 
        def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL);
        data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK;
@@ -560,11 +552,8 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
        if (def != data)
                WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5, data);
 
-       pcie_capability_read_word(adev->pdev, PCI_EXP_DEVCTL2, &devctl2);
-       data = def = devctl2;
-       data &= ~PCI_EXP_DEVCTL2_LTR_EN;
-       if (def != data)
-               pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2, (u16)data);
+       pcie_capability_clear_word(adev->pdev, PCI_EXP_DEVCTL2,
+                                  PCI_EXP_DEVCTL2_LTR_EN);
 
        ltr = pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_LTR);
 
@@ -572,15 +561,13 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
                pci_write_config_dword(adev->pdev, ltr + PCI_LTR_MAX_SNOOP_LAT, 0x10011001);
        }
 
-#if 0
-       /* regPSWUSP0_PCIE_LC_CNTL2 should be replace by PCIE_LC_CNTL2 or someone else ? */
-       def = data = RREG32_SOC15(NBIO, 0, regPSWUSP0_PCIE_LC_CNTL2);
-       data |= PSWUSP0_PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L1_MASK |
-               PSWUSP0_PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L23_MASK;
-       data &= ~PSWUSP0_PCIE_LC_CNTL2__LC_RCV_L0_TO_RCV_L0S_DIS_MASK;
+       def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL2);
+       data |= PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L1_MASK |
+               PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L23_MASK;
+       data &= ~PCIE_LC_CNTL2__LC_RCV_L0_TO_RCV_L0S_DIS_MASK;
        if (def != data)
-               WREG32_SOC15(NBIO, 0, regPSWUSP0_PCIE_LC_CNTL2, data);
-#endif
+               WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL2, data);
+
        def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL4);
        data |= PCIE_LC_CNTL4__LC_L1_POWERDOWN_MASK;
        if (def != data)
@@ -591,7 +578,12 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
        if (def != data)
                WREG32_SOC15(PCIE, 0, regPCIE_LC_RXRECOVER_RXSTANDBY_CNTL, data);
 
-       nbif_v6_3_1_program_ltr(adev);
+       /*
+        * Do not enable endpoint LTR unless the Root Complex and every
+        * upstream switch support it.
+        */
+       if (adev->pdev->ltr_path)
+               nbif_v6_3_1_program_ltr(adev);
 
        def = data = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP3);
        data |= 0x5DE0 << RCC_STRAP0_RCC_BIF_STRAP3__STRAP_VLINK_ASPM_IDLE_TIMER__SHIFT;