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, > };