Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da146d3b authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu: fix amdgpu_need_full_reset (v2)



IP types are not an index.  Each asic may have number and
type of IPs.  Properly check the the type rather than
using the type id as an index.

v2: fix all the IPs to not use IP type as an idx as well.

Reviewed-by: default avatarChunming Zhou <david1.zhou@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent aee3960a
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -2075,6 +2075,7 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)
		if (!adev->ip_block_status[i].valid)
			continue;
		if (adev->ip_blocks[i].funcs->check_soft_reset)
			adev->ip_block_status[i].hang =
				adev->ip_blocks[i].funcs->check_soft_reset(adev);
		if (adev->ip_block_status[i].hang) {
			DRM_INFO("IP block:%d is hang!\n", i);
@@ -2104,13 +2105,21 @@ static int amdgpu_pre_soft_reset(struct amdgpu_device *adev)

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_SMC].hang ||
	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang ||
	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) {
	int i;

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_block_status[i].valid)
			continue;
		if ((adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) ||
		    (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) ||
		    (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_ACP) ||
		    (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_DCE)) {
			if (adev->ip_block_status[i].hang) {
				DRM_INFO("Some block need full reset!\n");
				return true;
			}
		}
	}
	return false;
}

+2 −10
Original line number Diff line number Diff line
@@ -3188,16 +3188,11 @@ static int dce_v10_0_wait_for_idle(void *handle)
	return 0;
}

static int dce_v10_0_check_soft_reset(void *handle)
static bool dce_v10_0_check_soft_reset(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (dce_v10_0_is_display_hung(adev))
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = true;
	else
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = false;

	return 0;
	return dce_v10_0_is_display_hung(adev);
}

static int dce_v10_0_soft_reset(void *handle)
@@ -3205,9 +3200,6 @@ static int dce_v10_0_soft_reset(void *handle)
	u32 srbm_soft_reset = 0, tmp;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang)
		return 0;

	if (dce_v10_0_is_display_hung(adev))
		srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;

+9 −8
Original line number Diff line number Diff line
@@ -5144,7 +5144,7 @@ static int gfx_v8_0_wait_for_idle(void *handle)
	return -ETIMEDOUT;
}

static int gfx_v8_0_check_soft_reset(void *handle)
static bool gfx_v8_0_check_soft_reset(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
@@ -5196,16 +5196,14 @@ static int gfx_v8_0_check_soft_reset(void *handle)
						SRBM_SOFT_RESET, SOFT_RESET_SEM, 1);

	if (grbm_soft_reset || srbm_soft_reset) {
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true;
		adev->gfx.grbm_soft_reset = grbm_soft_reset;
		adev->gfx.srbm_soft_reset = srbm_soft_reset;
		return true;
	} else {
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false;
		adev->gfx.grbm_soft_reset = 0;
		adev->gfx.srbm_soft_reset = 0;
		return false;
	}

	return 0;
}

static void gfx_v8_0_inactive_hqd(struct amdgpu_device *adev,
@@ -5233,7 +5231,8 @@ static int gfx_v8_0_pre_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)
	if ((!adev->gfx.grbm_soft_reset) &&
	    (!adev->gfx.srbm_soft_reset))
		return 0;

	grbm_soft_reset = adev->gfx.grbm_soft_reset;
@@ -5271,7 +5270,8 @@ static int gfx_v8_0_soft_reset(void *handle)
	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
	u32 tmp;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
	if ((!adev->gfx.grbm_soft_reset) &&
	    (!adev->gfx.srbm_soft_reset))
		return 0;

	grbm_soft_reset = adev->gfx.grbm_soft_reset;
@@ -5341,7 +5341,8 @@ 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)
	if ((!adev->gfx.grbm_soft_reset) &&
	    (!adev->gfx.srbm_soft_reset))
		return 0;

	grbm_soft_reset = adev->gfx.grbm_soft_reset;
+6 −7
Original line number Diff line number Diff line
@@ -1099,7 +1099,7 @@ static int gmc_v8_0_wait_for_idle(void *handle)

}

static int gmc_v8_0_check_soft_reset(void *handle)
static bool gmc_v8_0_check_soft_reset(void *handle)
{
	u32 srbm_soft_reset = 0;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1116,20 +1116,19 @@ static int gmc_v8_0_check_soft_reset(void *handle)
							SRBM_SOFT_RESET, SOFT_RESET_MC, 1);
	}
	if (srbm_soft_reset) {
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = true;
		adev->mc.srbm_soft_reset = srbm_soft_reset;
		return true;
	} else {
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = false;
		adev->mc.srbm_soft_reset = 0;
		return false;
	}
	return 0;
}

static int gmc_v8_0_pre_soft_reset(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
	if (!adev->mc.srbm_soft_reset)
		return 0;

	gmc_v8_0_mc_stop(adev, &adev->mc.save);
@@ -1145,7 +1144,7 @@ static int gmc_v8_0_soft_reset(void *handle)
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	u32 srbm_soft_reset;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
	if (!adev->mc.srbm_soft_reset)
		return 0;
	srbm_soft_reset = adev->mc.srbm_soft_reset;

@@ -1175,7 +1174,7 @@ 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)
	if (!adev->mc.srbm_soft_reset)
		return 0;

	gmc_v8_0_mc_resume(adev, &adev->mc.save);
+6 −8
Original line number Diff line number Diff line
@@ -1268,7 +1268,7 @@ static int sdma_v3_0_wait_for_idle(void *handle)
	return -ETIMEDOUT;
}

static int sdma_v3_0_check_soft_reset(void *handle)
static bool sdma_v3_0_check_soft_reset(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	u32 srbm_soft_reset = 0;
@@ -1281,14 +1281,12 @@ static int sdma_v3_0_check_soft_reset(void *handle)
	}

	if (srbm_soft_reset) {
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = true;
		adev->sdma.srbm_soft_reset = srbm_soft_reset;
		return true;
	} else {
		adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = false;
		adev->sdma.srbm_soft_reset = 0;
		return false;
	}

	return 0;
}

static int sdma_v3_0_pre_soft_reset(void *handle)
@@ -1296,7 +1294,7 @@ static int sdma_v3_0_pre_soft_reset(void *handle)
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	u32 srbm_soft_reset = 0;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
	if (!adev->sdma.srbm_soft_reset)
		return 0;

	srbm_soft_reset = adev->sdma.srbm_soft_reset;
@@ -1315,7 +1313,7 @@ static int sdma_v3_0_post_soft_reset(void *handle)
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	u32 srbm_soft_reset = 0;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
	if (!adev->sdma.srbm_soft_reset)
		return 0;

	srbm_soft_reset = adev->sdma.srbm_soft_reset;
@@ -1335,7 +1333,7 @@ static int sdma_v3_0_soft_reset(void *handle)
	u32 srbm_soft_reset = 0;
	u32 tmp;

	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
	if (!adev->sdma.srbm_soft_reset)
		return 0;

	srbm_soft_reset = adev->sdma.srbm_soft_reset;
Loading