[Public] > -----Original Message----- > From: Ilpo Järvinen <ilpo.jarvi...@linux.intel.com> > Sent: Monday, July 17, 2023 8:05 AM > To: linux-...@vger.kernel.org; Bjorn Helgaas <bhelg...@google.com>; Lorenzo > Pieralisi <lorenzo.pieral...@arm.com>; Rob Herring <r...@kernel.org>; > Krzysztof Wilczyński <k...@linux.com>; Emmanuel Grumbach > <emmanuel.grumb...@intel.com>; Rafael J . Wysocki <raf...@kernel.org>; > Heiner Kallweit <hkallwe...@gmail.com>; Lukas Wunner <lu...@wunner.de>; > Andy Shevchenko <andriy.shevche...@linux.intel.com>; Deucher, Alexander > <alexander.deuc...@amd.com>; Koenig, Christian > <christian.koe...@amd.com>; Pan, Xinhui <xinhui....@amd.com>; David > Airlie <airl...@gmail.com>; Daniel Vetter <dan...@ffwll.ch>; amd- > g...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; linux- > ker...@vger.kernel.org > Cc: Dean Luick <dean.lu...@cornelisnetworks.com>; Jonas Dreßler > <ver...@v0yd.nl>; Ilpo Järvinen <ilpo.jarvi...@linux.intel.com>; > sta...@vger.kernel.org > Subject: [PATCH v5 06/11] drm/radeon: Use RMW accessors for changing > LNKCTL > > 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. > > Fixes: 8a7cd27679d0 ("drm/radeon/cik: add support for pcie gen1/2/3 > switching") > Fixes: b9d305dfb66c ("drm/radeon: implement pcie gen2/3 support for SI") > Suggested-by: Lukas Wunner <lu...@wunner.de> > Signed-off-by: Ilpo Järvinen <ilpo.jarvi...@linux.intel.com> > Cc: sta...@vger.kernel.org
For this and the amdgpu patch: Acked-by: Alex Deucher <alexander.deuc...@amd.com> I'm not sure if this is stable material however. Is there some issue today? > --- > drivers/gpu/drm/radeon/cik.c | 36 ++++++++++------------------------- > drivers/gpu/drm/radeon/si.c | 37 ++++++++++-------------------------- > 2 files changed, 20 insertions(+), 53 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c > index 5819737c21c6..a6f3c811ceb8 100644 > --- a/drivers/gpu/drm/radeon/cik.c > +++ b/drivers/gpu/drm/radeon/cik.c > @@ -9534,17 +9534,8 @@ static void cik_pcie_gen3_enable(struct > radeon_device *rdev) > 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(rdev->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(rdev->pdev, > PCI_EXP_LNKCTL, > - tmp16); > + pcie_capability_set_word(root, PCI_EXP_LNKCTL, > PCI_EXP_LNKCTL_HAWD); > + pcie_capability_set_word(rdev->pdev, > PCI_EXP_LNKCTL, > +PCI_EXP_LNKCTL_HAWD); > > tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1); > max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) > >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -9591,21 +9582,14 @@ static > void cik_pcie_gen3_enable(struct radeon_device *rdev) > 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(rdev->pdev, > - PCI_EXP_LNKCTL, > - &tmp16); > - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; > - tmp16 |= (gpu_cfg & > PCI_EXP_LNKCTL_HAWD); > - pcie_capability_write_word(rdev->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(rdev- > >pdev, PCI_EXP_LNKCTL, > + > PCI_EXP_LNKCTL_HAWD, > + gpu_cfg & > + > PCI_EXP_LNKCTL_HAWD); > > /* linkctl2 */ > pcie_capability_read_word(root, > PCI_EXP_LNKCTL2, diff --git a/drivers/gpu/drm/radeon/si.c > b/drivers/gpu/drm/radeon/si.c index 8d5e4b25609d..a91012447b56 > 100644 > --- a/drivers/gpu/drm/radeon/si.c > +++ b/drivers/gpu/drm/radeon/si.c > @@ -7131,17 +7131,8 @@ static void si_pcie_gen3_enable(struct > radeon_device *rdev) > 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(rdev->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(rdev->pdev, > PCI_EXP_LNKCTL, > - tmp16); > + pcie_capability_set_word(root, PCI_EXP_LNKCTL, > PCI_EXP_LNKCTL_HAWD); > + pcie_capability_set_word(rdev->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; @@ -7188,22 +7179,14 @@ static > void si_pcie_gen3_enable(struct radeon_device *rdev) > 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(rdev->pdev, > - PCI_EXP_LNKCTL, > - &tmp16); > - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; > - tmp16 |= (gpu_cfg & > PCI_EXP_LNKCTL_HAWD); > - pcie_capability_write_word(rdev->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(rdev- > >pdev, PCI_EXP_LNKCTL, > + > PCI_EXP_LNKCTL_HAWD, > + gpu_cfg & > + > PCI_EXP_LNKCTL_HAWD); > > /* linkctl2 */ > pcie_capability_read_word(root, > PCI_EXP_LNKCTL2, > -- > 2.30.2