Re: [PATCH] drm/amdgpu/si: initial support for GPU reset

2020-07-27 Thread Christian König

Am 27.07.20 um 19:34 schrieb Alex Deucher:

Ported from radeon.

Signed-off-by: Alex Deucher 


Acked-by: Christian König 


---
  drivers/gpu/drm/amd/amdgpu/si.c | 92 -
  1 file changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 1b449291f068..a7a45f06c8f3 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1215,10 +1215,98 @@ static bool si_read_bios_from_rom(struct amdgpu_device 
*adev,
return true;
  }
  
-//xxx: not implemented

+static void si_set_clk_bypass_mode(struct amdgpu_device *adev)
+{
+   u32 tmp, i;
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL);
+   tmp |= SPLL_BYPASS_EN;
+   WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+   tmp |= SPLL_CTLREQ_CHG;
+   WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+   for (i = 0; i < adev->usec_timeout; i++) {
+   if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
+   break;
+   udelay(1);
+   }
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+   tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
+   WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+   tmp = RREG32(MPLL_CNTL_MODE);
+   tmp &= ~MPLL_MCLK_SEL;
+   WREG32(MPLL_CNTL_MODE, tmp);
+}
+
+static void si_spll_powerdown(struct amdgpu_device *adev)
+{
+   u32 tmp;
+
+   tmp = RREG32(SPLL_CNTL_MODE);
+   tmp |= SPLL_SW_DIR_CONTROL;
+   WREG32(SPLL_CNTL_MODE, tmp);
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL);
+   tmp |= SPLL_RESET;
+   WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL);
+   tmp |= SPLL_SLEEP;
+   WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+   tmp = RREG32(SPLL_CNTL_MODE);
+   tmp &= ~SPLL_SW_DIR_CONTROL;
+   WREG32(SPLL_CNTL_MODE, tmp);
+}
+
+static int si_gpu_pci_config_reset(struct amdgpu_device *adev)
+{
+   u32 i;
+   int r = -EINVAL;
+
+   dev_info(adev->dev, "GPU pci config reset\n");
+
+   /* set mclk/sclk to bypass */
+   si_set_clk_bypass_mode(adev);
+   /* powerdown spll */
+   si_spll_powerdown(adev);
+   /* disable BM */
+   pci_clear_master(adev->pdev);
+   /* reset */
+   amdgpu_device_pci_config_reset(adev);
+
+   udelay(100);
+
+   /* wait for asic to come out of reset */
+   for (i = 0; i < adev->usec_timeout; i++) {
+   if (RREG32(mmCONFIG_MEMSIZE) != 0x) {
+   /* enable BM */
+   pci_set_master(adev->pdev);
+   adev->has_hw_reset = true;
+   r = 0;
+   break;
+   }
+   udelay(1);
+   }
+
+   return r;
+}
+
  static int si_asic_reset(struct amdgpu_device *adev)
  {
-   return 0;
+   int r;
+
+   amdgpu_atombios_scratch_regs_engine_hung(adev, true);
+
+   r = si_gpu_pci_config_reset(adev);
+
+   amdgpu_atombios_scratch_regs_engine_hung(adev, false);
+
+   return r;
  }
  
  static bool si_asic_supports_baco(struct amdgpu_device *adev)


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH] drm/amdgpu/si: initial support for GPU reset

2020-07-27 Thread Alex Deucher
Ported from radeon.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/si.c | 92 -
 1 file changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 1b449291f068..a7a45f06c8f3 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1215,10 +1215,98 @@ static bool si_read_bios_from_rom(struct amdgpu_device 
*adev,
return true;
 }
 
-//xxx: not implemented
+static void si_set_clk_bypass_mode(struct amdgpu_device *adev)
+{
+   u32 tmp, i;
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL);
+   tmp |= SPLL_BYPASS_EN;
+   WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+   tmp |= SPLL_CTLREQ_CHG;
+   WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+   for (i = 0; i < adev->usec_timeout; i++) {
+   if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
+   break;
+   udelay(1);
+   }
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+   tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
+   WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+   tmp = RREG32(MPLL_CNTL_MODE);
+   tmp &= ~MPLL_MCLK_SEL;
+   WREG32(MPLL_CNTL_MODE, tmp);
+}
+
+static void si_spll_powerdown(struct amdgpu_device *adev)
+{
+   u32 tmp;
+
+   tmp = RREG32(SPLL_CNTL_MODE);
+   tmp |= SPLL_SW_DIR_CONTROL;
+   WREG32(SPLL_CNTL_MODE, tmp);
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL);
+   tmp |= SPLL_RESET;
+   WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+   tmp = RREG32(CG_SPLL_FUNC_CNTL);
+   tmp |= SPLL_SLEEP;
+   WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+   tmp = RREG32(SPLL_CNTL_MODE);
+   tmp &= ~SPLL_SW_DIR_CONTROL;
+   WREG32(SPLL_CNTL_MODE, tmp);
+}
+
+static int si_gpu_pci_config_reset(struct amdgpu_device *adev)
+{
+   u32 i;
+   int r = -EINVAL;
+
+   dev_info(adev->dev, "GPU pci config reset\n");
+
+   /* set mclk/sclk to bypass */
+   si_set_clk_bypass_mode(adev);
+   /* powerdown spll */
+   si_spll_powerdown(adev);
+   /* disable BM */
+   pci_clear_master(adev->pdev);
+   /* reset */
+   amdgpu_device_pci_config_reset(adev);
+
+   udelay(100);
+
+   /* wait for asic to come out of reset */
+   for (i = 0; i < adev->usec_timeout; i++) {
+   if (RREG32(mmCONFIG_MEMSIZE) != 0x) {
+   /* enable BM */
+   pci_set_master(adev->pdev);
+   adev->has_hw_reset = true;
+   r = 0;
+   break;
+   }
+   udelay(1);
+   }
+
+   return r;
+}
+
 static int si_asic_reset(struct amdgpu_device *adev)
 {
-   return 0;
+   int r;
+
+   amdgpu_atombios_scratch_regs_engine_hung(adev, true);
+
+   r = si_gpu_pci_config_reset(adev);
+
+   amdgpu_atombios_scratch_regs_engine_hung(adev, false);
+
+   return r;
 }
 
 static bool si_asic_supports_baco(struct amdgpu_device *adev)
-- 
2.25.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx