drm/amdgpu: implement gfx8 post_soft_reset
authorChunming Zhou <David1.Zhou@amd.com>
Fri, 15 Jul 2016 08:24:25 +0000 (16:24 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Aug 2016 15:32:06 +0000 (11:32 -0400)
Signed-off-by: Chunming Zhou <David1.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c

index 2bd2b19d46668218f0651274e17fc7c8d1b0a04f..1e553663e47dc647d4c2d4b0aee456693ce2fd80 100644 (file)
@@ -1978,7 +1978,6 @@ static bool amdgpu_need_full_reset(struct amdgpu_device *adev)
        if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang ||
            adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang ||
            adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang ||
-           adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang ||
            adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang ||
            adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang ||
            adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang ||
index 62ba7e550aee3920112e9fed44ec9740f0a7f7df..af0efa250d80d3e49ac10dfff7b056fe3a8aff97 100644 (file)
@@ -5229,6 +5229,49 @@ static int gfx_v8_0_soft_reset(void *handle)
        return 0;
 }
 
+static void gfx_v8_0_init_hqd(struct amdgpu_device *adev,
+                             struct amdgpu_ring *ring)
+{
+       vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
+       WREG32(mmCP_HQD_DEQUEUE_REQUEST, 0);
+       WREG32(mmCP_HQD_PQ_RPTR, 0);
+       WREG32(mmCP_HQD_PQ_WPTR, 0);
+       vi_srbm_select(adev, 0, 0, 0, 0);
+}
+
+static int gfx_v8_0_post_soft_reset(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
+
+       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
+               return 0;
+
+       grbm_soft_reset = adev->gfx.grbm_soft_reset;
+       srbm_soft_reset = adev->gfx.srbm_soft_reset;
+
+       if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) ||
+           REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX))
+               gfx_v8_0_cp_gfx_resume(adev);
+
+       if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) ||
+           REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPF) ||
+           REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPC) ||
+           REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPG)) {
+               int i;
+
+               for (i = 0; i < adev->gfx.num_compute_rings; i++) {
+                       struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
+
+                       gfx_v8_0_init_hqd(adev, ring);
+               }
+               gfx_v8_0_cp_compute_resume(adev);
+       }
+       gfx_v8_0_rlc_start(adev);
+
+       return 0;
+}
+
 /**
  * gfx_v8_0_get_gpu_clock_counter - return GPU clock counter snapshot
  *
@@ -6416,6 +6459,7 @@ const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
        .check_soft_reset = gfx_v8_0_check_soft_reset,
        .pre_soft_reset = gfx_v8_0_pre_soft_reset,
        .soft_reset = gfx_v8_0_soft_reset,
+       .post_soft_reset = gfx_v8_0_post_soft_reset,
        .set_clockgating_state = gfx_v8_0_set_clockgating_state,
        .set_powergating_state = gfx_v8_0_set_powergating_state,
 };