[PATCH] drm/amdgpu/si: initial support for GPU reset
Christian König
ckoenig.leichtzumerken at gmail.com
Mon Jul 27 19:37:03 UTC 2020
Am 27.07.20 um 19:34 schrieb Alex Deucher:
> Ported from radeon.
>
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Acked-by: Christian König <christian.koenig at amd.com>
> ---
> 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) != 0xffffffff) {
> + /* 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)
More information about the amd-gfx
mailing list