Commit 73dae652 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu: rework resume handling for display (v2)



Split resume into a 3rd step to handle displays when DCC is
enabled on DCN 4.0.1.  Move display after the buffer funcs
have been re-enabled so that the GPU will do the move and
properly set the DCC metadata for DCN.

v2: fix fence irq resume ordering

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 # 6.11.x
parent 1443dd3c
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -3762,7 +3762,7 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev)
 *
 * @adev: amdgpu_device pointer
 *
 * First resume function for hardware IPs.  The list of all the hardware
 * Second resume function for hardware IPs.  The list of all the hardware
 * IPs that make up the asic is walked and the resume callbacks are run for
 * all blocks except COMMON, GMC, and IH.  resume puts the hardware into a
 * functional state after a suspend and updates the software state as
@@ -3780,6 +3780,7 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
		if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE ||
		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)
			continue;
		r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
@@ -3790,6 +3791,36 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
	return 0;
}

/**
 * amdgpu_device_ip_resume_phase3 - run resume for hardware IPs
 *
 * @adev: amdgpu_device pointer
 *
 * Third resume function for hardware IPs.  The list of all the hardware
 * IPs that make up the asic is walked and the resume callbacks are run for
 * all DCE.  resume puts the hardware into a functional state after a suspend
 * and updates the software state as necessary.  This function is also used
 * for restoring the GPU after a GPU reset.
 *
 * Returns 0 on success, negative error code on failure.
 */
static int amdgpu_device_ip_resume_phase3(struct amdgpu_device *adev)
{
	int i, r;

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_blocks[i].status.valid || adev->ip_blocks[i].status.hw)
			continue;
		if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) {
			r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
			if (r)
				return r;
		}
	}

	return 0;
}

/**
 * amdgpu_device_ip_resume - run resume for hardware IPs
 *
@@ -3819,6 +3850,13 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
	if (adev->mman.buffer_funcs_ring->sched.ready)
		amdgpu_ttm_set_buffer_funcs_status(adev, true);

	if (r)
		return r;

	amdgpu_fence_driver_hw_init(adev);

	r = amdgpu_device_ip_resume_phase3(adev);

	return r;
}

@@ -4899,7 +4937,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients)
		dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);
		goto exit;
	}
	amdgpu_fence_driver_hw_init(adev);

	if (!adev->in_s0ix) {
		r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
@@ -5484,6 +5521,10 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context)
				if (tmp_adev->mman.buffer_funcs_ring->sched.ready)
					amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);

				r = amdgpu_device_ip_resume_phase3(tmp_adev);
				if (r)
					goto out;

				if (vram_lost)
					amdgpu_device_fill_reset_magic(tmp_adev);