]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amdgpu: Use RMW accessors for changing LNKCTL
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 17 Jul 2023 12:04:57 +0000 (15:04 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Sep 2023 07:48:23 +0000 (09:48 +0200)
[ Upstream commit ce7d88110b9ed5f33fe79ea6d4ed049fb0e57bce ]

Don't assume that only the driver would be accessing LNKCTL. ASPM policy
changes can trigger write to LNKCTL outside of driver's control.  And in
the case of upstream bridge, the driver does not even own the device it's
changing the registers for.

Use RMW capability accessors which do proper locking to avoid losing
concurrent updates to the register value.

Suggested-by: Lukas Wunner <lukas@wunner.de>
Fixes: a2e73f56fa62 ("drm/amdgpu: Add support for CIK parts")
Fixes: 62a37553414a ("drm/amdgpu: add si implementation v10")
Link: https://lore.kernel.org/r/20230717120503.15276-6-ilpo.jarvinen@linux.intel.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/amd/amdgpu/cik.c
drivers/gpu/drm/amd/amdgpu/si.c

index de6d10390ab2f195fcb3a03091f904ce1edf2c0c..9be6da37032a73b7d6adf6edebf86c5c6f2f284d 100644 (file)
@@ -1574,17 +1574,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
                        u16 bridge_cfg2, gpu_cfg2;
                        u32 max_lw, current_lw, tmp;
 
-                       pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-                                                 &bridge_cfg);
-                       pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
-                                                 &gpu_cfg);
-
-                       tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-                       pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-
-                       tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-                       pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
-                                                  tmp16);
+                       pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+                       pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
 
                        tmp = RREG32_PCIE(ixPCIE_LC_STATUS1);
                        max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >>
@@ -1637,21 +1628,14 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
                                msleep(100);
 
                                /* linkctl */
-                               pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-                                                         &tmp16);
-                               tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-                               tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-                               pcie_capability_write_word(root, PCI_EXP_LNKCTL,
-                                                          tmp16);
-
-                               pcie_capability_read_word(adev->pdev,
-                                                         PCI_EXP_LNKCTL,
-                                                         &tmp16);
-                               tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-                               tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-                               pcie_capability_write_word(adev->pdev,
-                                                          PCI_EXP_LNKCTL,
-                                                          tmp16);
+                               pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+                                                                  PCI_EXP_LNKCTL_HAWD,
+                                                                  bridge_cfg &
+                                                                  PCI_EXP_LNKCTL_HAWD);
+                               pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
+                                                                  PCI_EXP_LNKCTL_HAWD,
+                                                                  gpu_cfg &
+                                                                  PCI_EXP_LNKCTL_HAWD);
 
                                /* linkctl2 */
                                pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
index 7f99e130acd0663eec48e3e6149468fd2b833c45..fd34c2100bd9694911a59b88b2446e249d6628e8 100644 (file)
@@ -2276,17 +2276,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
                        u16 bridge_cfg2, gpu_cfg2;
                        u32 max_lw, current_lw, tmp;
 
-                       pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-                                                 &bridge_cfg);
-                       pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
-                                                 &gpu_cfg);
-
-                       tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-                       pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-
-                       tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-                       pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
-                                                  tmp16);
+                       pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+                       pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
 
                        tmp = RREG32_PCIE(PCIE_LC_STATUS1);
                        max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -2331,21 +2322,14 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
 
                                mdelay(100);
 
-                               pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-                                                         &tmp16);
-                               tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-                               tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-                               pcie_capability_write_word(root, PCI_EXP_LNKCTL,
-                                                          tmp16);
-
-                               pcie_capability_read_word(adev->pdev,
-                                                         PCI_EXP_LNKCTL,
-                                                         &tmp16);
-                               tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-                               tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-                               pcie_capability_write_word(adev->pdev,
-                                                          PCI_EXP_LNKCTL,
-                                                          tmp16);
+                               pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+                                                                  PCI_EXP_LNKCTL_HAWD,
+                                                                  bridge_cfg &
+                                                                  PCI_EXP_LNKCTL_HAWD);
+                               pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
+                                                                  PCI_EXP_LNKCTL_HAWD,
+                                                                  gpu_cfg &
+                                                                  PCI_EXP_LNKCTL_HAWD);
 
                                pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
                                                          &tmp16);