Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 414a0c50 authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by Greg Kroah-Hartman
Browse files

drm/amdgpu: Use RMW accessors for changing LNKCTL



[ 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: default avatarLukas Wunner <lukas@wunner.de>
Fixes: a2e73f56 ("drm/amdgpu: Add support for CIK parts")
Fixes: 62a37553 ("drm/amdgpu: add si implementation v10")
Link: https://lore.kernel.org/r/20230717120503.15276-6-ilpo.jarvinen@linux.intel.com


Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 80a23b62
Loading
Loading
Loading
Loading
+10 −26
Original line number Diff line number Diff line
@@ -1421,17 +1421,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) >>
@@ -1484,21 +1475,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,
+10 −26
Original line number Diff line number Diff line
@@ -1601,17 +1601,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;
@@ -1656,21 +1647,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);