Commit 1995e7d0 authored by Simona Vetter's avatar Simona Vetter
Browse files

Merge tag 'amd-drm-fixes-6.13-2024-12-04' of...

Merge tag 'amd-drm-fixes-6.13-2024-12-04' of https://gitlab.freedesktop.org/agd5f/linux

 into drm-fixes

amd-drm-fixes-6.13-2024-12-04:

amdgpu:
- Jpeg work handler fix for VCN 1.0
- HDP flush fixes
- ACPI EDID sanity check
- OLED panel backlight fix
- DC YCbCr fix
- DC Detile buffer size debugging
- DC prefetch calculation fix
- DC VTotal handling fix
- DC HBlank fix
- ISP fix
- SR-IOV fix
- Workload profile fixes
- DCN 4.0.1 resume fix

amdkfd:
- GC 12.x fix
- GC 9.4.x fix

Signed-off-by: default avatarSimona Vetter <simona.vetter@ffwll.ch>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241206190452.2571042-1-alexander.deucher@amd.com
parents 471f3a21 73dae652
Loading
Loading
Loading
Loading
+64 −26
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ const char *amdgpu_asic_name[] = {
	"LAST",
};

#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM - 1, 0)
#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM, 0)
/*
 * Default init level where all blocks are expected to be initialized. This is
 * the level of initialization expected by default and also after a full reset
@@ -3670,9 +3670,11 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
				continue;

			r = block->version->funcs->hw_init(&adev->ip_blocks[i]);
			DRM_INFO("RE-INIT-early: %s %s\n", block->version->funcs->name, r?"failed":"succeeded");
			if (r)
			if (r) {
				dev_err(adev->dev, "RE-INIT-early: %s failed\n",
					 block->version->funcs->name);
				return r;
			}
			block->status.hw = true;
		}
	}
@@ -3682,7 +3684,8 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)

static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
{
	int i, r;
	struct amdgpu_ip_block *block;
	int i, r = 0;

	static enum amd_ip_block_type ip_order[] = {
		AMD_IP_BLOCK_TYPE_SMC,
@@ -3697,34 +3700,28 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
	};

	for (i = 0; i < ARRAY_SIZE(ip_order); i++) {
		int j;
		struct amdgpu_ip_block *block;
		block = amdgpu_device_ip_get_ip_block(adev, ip_order[i]);

		for (j = 0; j < adev->num_ip_blocks; j++) {
			block = &adev->ip_blocks[j];

			if (block->version->type != ip_order[i] ||
				!block->status.valid ||
				block->status.hw)
		if (!block)
			continue;

		if (block->status.valid && !block->status.hw) {
			if (block->version->type == AMD_IP_BLOCK_TYPE_SMC) {
				r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
				if (r)
					return r;
				r = amdgpu_ip_block_resume(block);
			} else {
				r = block->version->funcs->hw_init(&adev->ip_blocks[i]);
				r = block->version->funcs->hw_init(block);
			}

			if (r) {
					DRM_ERROR("hw_init of IP block <%s> failed %d\n",
						  adev->ip_blocks[i].version->funcs->name, r);
					return r;
				dev_err(adev->dev, "RE-INIT-late: %s failed\n",
					 block->version->funcs->name);
				break;
			}
			block->status.hw = true;
		}
	}
	}

	return 0;
	return r;
}

/**
@@ -3765,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
@@ -3783,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]);
@@ -3793,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
 *
@@ -3822,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;
}

@@ -4902,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);
@@ -5487,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);

+8 −4
Original line number Diff line number Diff line
@@ -40,11 +40,13 @@
static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev,
				struct amdgpu_ring *ring)
{
	if (!ring || !ring->funcs->emit_wreg)
	if (!ring || !ring->funcs->emit_wreg) {
		WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
	else
		RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
	} else {
		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
	}
}

static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev,
				    struct amdgpu_ring *ring)
@@ -54,12 +56,14 @@ static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev,
	    amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 5))
		return;

	if (!ring || !ring->funcs->emit_wreg)
	if (!ring || !ring->funcs->emit_wreg) {
		WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);
	else
		RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE);
	} else {
		amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(
			HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
	}
}

static void hdp_v4_0_query_ras_error_count(struct amdgpu_device *adev,
					   void *ras_error_status)
+5 −2
Original line number Diff line number Diff line
@@ -31,17 +31,20 @@
static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev,
				struct amdgpu_ring *ring)
{
	if (!ring || !ring->funcs->emit_wreg)
	if (!ring || !ring->funcs->emit_wreg) {
		WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
	else
		RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
	} else {
		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
	}
}

static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev,
				    struct amdgpu_ring *ring)
{
	if (!ring || !ring->funcs->emit_wreg) {
		WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);
		RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE);
	} else {
		amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(
					HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
+4 −2
Original line number Diff line number Diff line
@@ -31,14 +31,16 @@
static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev,
				struct amdgpu_ring *ring)
{
	if (!ring || !ring->funcs->emit_wreg)
	if (!ring || !ring->funcs->emit_wreg) {
		WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
			0);
	else
		RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
	} else {
		amdgpu_ring_emit_wreg(ring,
			(adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
			0);
	}
}

static void hdp_v5_2_update_mem_power_gating(struct amdgpu_device *adev,
					     bool enable)
+4 −2
Original line number Diff line number Diff line
@@ -34,11 +34,13 @@
static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev,
				struct amdgpu_ring *ring)
{
	if (!ring || !ring->funcs->emit_wreg)
	if (!ring || !ring->funcs->emit_wreg) {
		WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
	else
		RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
	} else {
		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
	}
}

static void hdp_v6_0_update_clock_gating(struct amdgpu_device *adev,
					 bool enable)
Loading