]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amdgpu: Check swus/ds for switch state save
authorLijo Lazar <lijo.lazar@amd.com>
Mon, 29 Sep 2025 12:29:26 +0000 (17:59 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 7 Oct 2025 18:09:19 +0000 (14:09 -0400)
For saving switch state, check if the GPU is having SWUS/DS
architecture. Otherwise, skip saving.

Reported-by: Roman Elshin <roman.elshin@gmail.com>
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4602
Fixes: 1dd2fa0e00f1 ("drm/amdgpu: Save and restore switch state")
Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

index a77000c2e0bbf58d8e628b829077c99230a93fee..929936c8d87caa120864d9a470ef3ada1cc9cac1 100644 (file)
@@ -7157,28 +7157,35 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
 
 static void amdgpu_device_cache_switch_state(struct amdgpu_device *adev)
 {
-       struct pci_dev *parent = pci_upstream_bridge(adev->pdev);
+       struct pci_dev *swus, *swds;
        int r;
 
-       if (!parent || parent->vendor != PCI_VENDOR_ID_ATI)
+       swds = pci_upstream_bridge(adev->pdev);
+       if (!swds || swds->vendor != PCI_VENDOR_ID_ATI ||
+           pci_pcie_type(swds) != PCI_EXP_TYPE_DOWNSTREAM)
+               return;
+       swus = pci_upstream_bridge(swds);
+       if (!swus ||
+           (swus->vendor != PCI_VENDOR_ID_ATI &&
+            swus->vendor != PCI_VENDOR_ID_AMD) ||
+           pci_pcie_type(swus) != PCI_EXP_TYPE_UPSTREAM)
                return;
 
        /* If already saved, return */
        if (adev->pcie_reset_ctx.swus)
                return;
        /* Upstream bridge is ATI, assume it's SWUS/DS architecture */
-       r = pci_save_state(parent);
+       r = pci_save_state(swds);
        if (r)
                return;
-       adev->pcie_reset_ctx.swds_pcistate = pci_store_saved_state(parent);
+       adev->pcie_reset_ctx.swds_pcistate = pci_store_saved_state(swds);
 
-       parent = pci_upstream_bridge(parent);
-       r = pci_save_state(parent);
+       r = pci_save_state(swus);
        if (r)
                return;
-       adev->pcie_reset_ctx.swus_pcistate = pci_store_saved_state(parent);
+       adev->pcie_reset_ctx.swus_pcistate = pci_store_saved_state(swus);
 
-       adev->pcie_reset_ctx.swus = parent;
+       adev->pcie_reset_ctx.swus = swus;
 }
 
 static void amdgpu_device_load_switch_state(struct amdgpu_device *adev)