Commit f6eac56d authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'amd-drm-fixes-6.19-2026-01-06' of...

Merge tag 'amd-drm-fixes-6.19-2026-01-06' of https://gitlab.freedesktop.org/agd5f/linux

 into drm-fixes

amd-drm-fixes-6.19-2026-01-06:

amdgpu:
- Clang fixes
- Navi1x PCIe DPM fixes
- Ring reset fixes
- ISP suspend fix
- Analog DC fixes
- VPE fixes
- Mode1 reset fix

radeon:
- Variable sized array fix

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260107223315.16095-1-alexander.deucher@amd.com
parents a5f207e2 6b2989ac
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -3445,11 +3445,10 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
		    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
		     adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA))
			continue;
		/* skip CG for VCE/UVD/VPE, it's handled specially */
		/* skip CG for VCE/UVD, it's handled specially */
		if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
		    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
		    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN &&
		    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VPE &&
		    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_JPEG &&
		    adev->ip_blocks[i].version->funcs->set_powergating_state) {
			/* enable powergating to save power */
@@ -5867,6 +5866,9 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev)
	if (ret)
		goto mode1_reset_failed;

	/* enable mmio access after mode 1 reset completed */
	adev->no_hw_access = false;

	amdgpu_device_load_pci_state(adev->pdev);
	ret = amdgpu_psp_wait_for_bootloader(adev);
	if (ret)
+31 −5
Original line number Diff line number Diff line
@@ -89,6 +89,16 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring)
	return seq;
}

static void amdgpu_fence_save_fence_wptr_start(struct amdgpu_fence *af)
{
	af->fence_wptr_start = af->ring->wptr;
}

static void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af)
{
	af->fence_wptr_end = af->ring->wptr;
}

/**
 * amdgpu_fence_emit - emit a fence on the requested ring
 *
@@ -116,8 +126,10 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
		       &ring->fence_drv.lock,
		       adev->fence_context + ring->idx, seq);

	amdgpu_fence_save_fence_wptr_start(af);
	amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
			       seq, flags | AMDGPU_FENCE_FLAG_INT);
	amdgpu_fence_save_fence_wptr_end(af);
	amdgpu_fence_save_wptr(af);
	pm_runtime_get_noresume(adev_to_drm(adev)->dev);
	ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
@@ -709,6 +721,7 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
	struct amdgpu_ring *ring = af->ring;
	unsigned long flags;
	u32 seq, last_seq;
	bool reemitted = false;

	last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
	seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
@@ -726,7 +739,9 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
		if (unprocessed && !dma_fence_is_signaled_locked(unprocessed)) {
			fence = container_of(unprocessed, struct amdgpu_fence, base);

			if (fence == af)
			if (fence->reemitted > 1)
				reemitted = true;
			else if (fence == af)
				dma_fence_set_error(&fence->base, -ETIME);
			else if (fence->context == af->context)
				dma_fence_set_error(&fence->base, -ECANCELED);
@@ -734,9 +749,12 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
		rcu_read_unlock();
	} while (last_seq != seq);
	spin_unlock_irqrestore(&ring->fence_drv.lock, flags);
	/* signal the guilty fence */
	amdgpu_fence_write(ring, (u32)af->base.seqno);
	amdgpu_fence_process(ring);

	if (reemitted) {
		/* if we've already reemitted once then just cancel everything */
		amdgpu_fence_driver_force_completion(af->ring);
		af->ring->ring_backup_entries_to_copy = 0;
	}
}

void amdgpu_fence_save_wptr(struct amdgpu_fence *af)
@@ -784,10 +802,18 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
			/* save everything if the ring is not guilty, otherwise
			 * just save the content from other contexts.
			 */
			if (!guilty_fence || (fence->context != guilty_fence->context))
			if (!fence->reemitted &&
			    (!guilty_fence || (fence->context != guilty_fence->context))) {
				amdgpu_ring_backup_unprocessed_command(ring, wptr,
								       fence->wptr);
			} else if (!fence->reemitted) {
				/* always save the fence */
				amdgpu_ring_backup_unprocessed_command(ring,
								       fence->fence_wptr_start,
								       fence->fence_wptr_end);
			}
			wptr = fence->wptr;
			fence->reemitted++;
		}
		rcu_read_unlock();
	} while (last_seq != seq);
+24 −0
Original line number Diff line number Diff line
@@ -318,12 +318,36 @@ void isp_kernel_buffer_free(void **buf_obj, u64 *gpu_addr, void **cpu_addr)
}
EXPORT_SYMBOL(isp_kernel_buffer_free);

static int isp_resume(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_device *adev = ip_block->adev;
	struct amdgpu_isp *isp = &adev->isp;

	if (isp->funcs->hw_resume)
		return isp->funcs->hw_resume(isp);

	return -ENODEV;
}

static int isp_suspend(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_device *adev = ip_block->adev;
	struct amdgpu_isp *isp = &adev->isp;

	if (isp->funcs->hw_suspend)
		return isp->funcs->hw_suspend(isp);

	return -ENODEV;
}

static const struct amd_ip_funcs isp_ip_funcs = {
	.name = "isp_ip",
	.early_init = isp_early_init,
	.hw_init = isp_hw_init,
	.hw_fini = isp_hw_fini,
	.is_idle = isp_is_idle,
	.suspend = isp_suspend,
	.resume = isp_resume,
	.set_clockgating_state = isp_set_clockgating_state,
	.set_powergating_state = isp_set_powergating_state,
};
+2 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ struct amdgpu_isp;
struct isp_funcs {
	int (*hw_init)(struct amdgpu_isp *isp);
	int (*hw_fini)(struct amdgpu_isp *isp);
	int (*hw_suspend)(struct amdgpu_isp *isp);
	int (*hw_resume)(struct amdgpu_isp *isp);
};

struct amdgpu_isp {
+6 −0
Original line number Diff line number Diff line
@@ -201,6 +201,9 @@ static enum amd_ip_block_type
		type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ?
				   AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN;
		break;
	case AMDGPU_HW_IP_VPE:
		type = AMD_IP_BLOCK_TYPE_VPE;
		break;
	default:
		type = AMD_IP_BLOCK_TYPE_NUM;
		break;
@@ -721,6 +724,9 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
		case AMD_IP_BLOCK_TYPE_UVD:
			count = adev->uvd.num_uvd_inst;
			break;
		case AMD_IP_BLOCK_TYPE_VPE:
			count = adev->vpe.num_instances;
			break;
		/* For all other IP block types not listed in the switch statement
		 * the ip status is valid here and the instance count is one.
		 */
Loading