[PATCH 10/14] drm/amdgpu: implement gmc8 check/pre/post_soft_reset
Christian König
deathsimple at vodafone.de
Tue Jul 19 09:23:41 UTC 2016
Am 19.07.2016 um 10:13 schrieb Chunming Zhou:
> Change-Id: Iadb48fd15f047f04d9a1d4c02661369ae9b79f1a
> Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 57 ++++++++++++++++++++++-------------
> 2 files changed, 37 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 26f9761..73234a4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1981,6 +1981,7 @@ struct amdgpu_ip_block_status {
> bool hang;
> u32 grbm_soft_reset;
> u32 srbm_soft_reset;
> + struct amdgpu_mode_mc_save save;
Again move that into struct amdgpu_mc.
Christian.
> };
>
> struct amdgpu_device {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> index 961f34d..27314dd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> @@ -1127,9 +1127,8 @@ static int gmc_v8_0_wait_for_idle(void *handle)
>
> }
>
> -static int gmc_v8_0_soft_reset(void *handle)
> +static int gmc_v8_0_check_soft_reset(void *handle)
> {
> - struct amdgpu_mode_mc_save save;
> u32 srbm_soft_reset = 0;
> struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> u32 tmp = RREG32(mmSRBM_STATUS);
> @@ -1144,33 +1143,46 @@ static int gmc_v8_0_soft_reset(void *handle)
> srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
> SRBM_SOFT_RESET, SOFT_RESET_MC, 1);
> }
> -
> if (srbm_soft_reset) {
> - gmc_v8_0_mc_stop(adev, &save);
> - if (gmc_v8_0_wait_for_idle(adev)) {
> - dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
> - }
> + adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = true;
> + adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].grbm_soft_reset = 0;
> + adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].srbm_soft_reset = srbm_soft_reset;
> + } else {
> + adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = false;
> + adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].grbm_soft_reset = 0;
> + adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].srbm_soft_reset = 0;
> + }
> + return 0;
> +}
>
> +static int gmc_v8_0_pre_soft_reset(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>
> - tmp = RREG32(mmSRBM_SOFT_RESET);
> - tmp |= srbm_soft_reset;
> - dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
> - WREG32(mmSRBM_SOFT_RESET, tmp);
> - tmp = RREG32(mmSRBM_SOFT_RESET);
> + if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
> + return 0;
>
> - udelay(50);
> + gmc_v8_0_mc_stop(adev, &adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].save);
> + if (gmc_v8_0_wait_for_idle(adev)) {
> + dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
> + }
>
> - tmp &= ~srbm_soft_reset;
> - WREG32(mmSRBM_SOFT_RESET, tmp);
> - tmp = RREG32(mmSRBM_SOFT_RESET);
> + return 0;
> +}
>
> - /* Wait a little for things to settle down */
> - udelay(50);
> +static int gmc_v8_0_soft_reset(void *handle)
> +{
> + return 0;
> +}
>
> - gmc_v8_0_mc_resume(adev, &save);
> - udelay(50);
> - }
> +static int gmc_v8_0_post_soft_reset(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +
> + if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
> + return 0;
>
> + gmc_v8_0_mc_resume(adev, &adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].save);
> return 0;
> }
>
> @@ -1441,7 +1453,10 @@ const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
> .resume = gmc_v8_0_resume,
> .is_idle = gmc_v8_0_is_idle,
> .wait_for_idle = gmc_v8_0_wait_for_idle,
> + .check_soft_reset = gmc_v8_0_check_soft_reset,
> + .pre_soft_reset = gmc_v8_0_pre_soft_reset,
> .soft_reset = gmc_v8_0_soft_reset,
> + .post_soft_reset = gmc_v8_0_post_soft_reset,
> .set_clockgating_state = gmc_v8_0_set_clockgating_state,
> .set_powergating_state = gmc_v8_0_set_powergating_state,
> };
More information about the amd-gfx
mailing list