Commit 490fd933 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-next-2025-11-14-1' of...

Merge tag 'drm-misc-next-2025-11-14-1' of https://gitlab.freedesktop.org/drm/misc/kernel

 into drm-next

drm-misc-next for v6.19:

UAPI Changes:
- Add sysfs entries, coredump support and uevents to QAIC.
- Add fdinfo memory statistics to ivpu.

Cross-subsystem Changes:
- Handle stub fence initialization during module init.
- Stop using system_wq in scheduler and drivers.

Core Changes:
- Documentation updates to ttm, vblank.
- Add EDID quirk for sharp panel.
- Use drm_crtc_vblank_(crtc,waitqueue) more in core and drivers.

Driver Changes:
- Small updates and fixes to panfrost, amdxdna, vmwgfx, ast, ivpu.
- Handle preemption in amdxdna.
- Add PM support to qaic.
- Huge refactor of sun4i's layer code to decouple plane code from output
  and improve support for DE33.
- Add larger page and compression support to nouveau.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patch.msgid.link/1ad3ea69-d029-4a21-8b3d-6b264b1b2a30@linux.intel.com
parents 727bf2dc ca258341
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
What:		/sys/bus/pci/drivers/qaic/XXXX:XX:XX.X/accel/accel<minor_nr>/dbc<N>_state
Date:		October 2025
KernelVersion:	6.19
Contact:	Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Description:	Represents the current state of DMA Bridge channel (DBC). Below are the possible
		states:

		===================	==========================================================
		IDLE (0)		DBC is free and can be activated
		ASSIGNED (1)		DBC is activated and a workload is running on device
		BEFORE_SHUTDOWN (2)	Sub-system associated with this workload has crashed and
					it will shutdown soon
		AFTER_SHUTDOWN (3)	Sub-system associated with this workload has crashed and
					it has shutdown
		BEFORE_POWER_UP (4)	Sub-system associated with this workload is shutdown and
					it will be powered up soon
		AFTER_POWER_UP (5)	Sub-system associated with this workload is now powered up
		===================	==========================================================
Users:		Any userspace application or clients interested in DBC state.
+23 −2
Original line number Diff line number Diff line
@@ -487,8 +487,8 @@ one user crashes, the fallout of that should be limited to that workload and not
impact other workloads. SSR accomplishes this.

If a particular workload crashes, QSM notifies the host via the QAIC_SSR MHI
channel. This notification identifies the workload by it's assigned DBC. A
multi-stage recovery process is then used to cleanup both sides, and get the
channel. This notification identifies the workload by its assigned DBC. A
multi-stage recovery process is then used to cleanup both sides, and gets the
DBC/NSPs into a working state.

When SSR occurs, any state in the workload is lost. Any inputs that were in
@@ -496,6 +496,27 @@ process, or queued by not yet serviced, are lost. The loaded artifacts will
remain in on-card DDR, but the host will need to re-activate the workload if
it desires to recover the workload.

When SSR occurs for a specific NSP, the assigned DBC goes through the
following state transactions in order:

DBC_STATE_BEFORE_SHUTDOWN
	Indicates that the affected NSP was found in an unrecoverable error
	condition.
DBC_STATE_AFTER_SHUTDOWN
	Indicates that the NSP is under reset.
DBC_STATE_BEFORE_POWER_UP
	Indicates that the NSP's debug information has been collected, and is
	ready to be collected by the host (if desired). At that stage the NSP
	is restarted by QSM.
DBC_STATE_AFTER_POWER_UP
	Indicates that the NSP has been restarted, fully operational and is
	in idle state.

SSR also has an optional crashdump collection feature. If enabled, the host can
collect the memory dump for the crashed NSP and dump it to the user space via
the dev_coredump subsystem. The host can also decline the crashdump collection
request from the device.

Reliability, Accessibility, Serviceability (RAS)
================================================

+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@ properties:
          - enum:
              - renesas,r9a07g054-du    # RZ/V2L
          - const: renesas,r9a07g044-du # RZ/G2L fallback
      - items:
          - const: renesas,r9a09g056-du # RZ/V2N
          - const: renesas,r9a09g057-du # RZ/V2H(P) fallback

  reg:
    maxItems: 1
+4 −3
Original line number Diff line number Diff line
@@ -189,7 +189,6 @@ aie2_sched_notify(struct amdxdna_sched_job *job)

	up(&job->hwctx->priv->job_sem);
	job->job_done = true;
	dma_fence_put(fence);
	mmput_async(job->mm);
	aie2_job_put(job);
}
@@ -691,17 +690,19 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx)
	xdna = hwctx->client->xdna;

	XDNA_DBG(xdna, "%s sequence number %lld", hwctx->name, hwctx->priv->seq);
	drm_sched_entity_destroy(&hwctx->priv->entity);

	aie2_hwctx_wait_for_idle(hwctx);

	/* Request fw to destroy hwctx and cancel the rest pending requests */
	aie2_release_resource(hwctx);

	mutex_unlock(&xdna->dev_lock);
	drm_sched_entity_destroy(&hwctx->priv->entity);

	/* Wait for all submitted jobs to be completed or canceled */
	wait_event(hwctx->priv->job_free_wq,
		   atomic64_read(&hwctx->job_submit_cnt) ==
		   atomic64_read(&hwctx->job_free_cnt));
	mutex_lock(&xdna->dev_lock);

	drm_sched_fini(&hwctx->priv->sched);
	aie2_ctx_syncobj_destroy(hwctx);
+95 −0
Original line number Diff line number Diff line
@@ -210,6 +210,14 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct
	hwctx->fw_ctx_id = resp.context_id;
	WARN_ONCE(hwctx->fw_ctx_id == -1, "Unexpected context id");

	if (ndev->force_preempt_enabled) {
		ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FORCE_PREEMPT, &hwctx->fw_ctx_id);
		if (ret) {
			XDNA_ERR(xdna, "failed to enable force preempt %d", ret);
			return ret;
		}
	}

	cq_pair = &resp.cq_pair[0];
	x2i.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.head_addr);
	x2i.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.tail_addr);
@@ -601,6 +609,11 @@ aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
	return 0;
}

static int aie2_cmdlist_unsupp(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
{
	return -EOPNOTSUPP;
}

static u32 aie2_get_chain_msg_op(u32 cmd_op)
{
	switch (cmd_op) {
@@ -621,6 +634,8 @@ static struct aie2_exec_msg_ops legacy_exec_message_ops = {
	.init_chain_req = aie2_init_exec_chain_req,
	.fill_cf_slot = aie2_cmdlist_fill_cf,
	.fill_dpu_slot = aie2_cmdlist_fill_dpu,
	.fill_preempt_slot = aie2_cmdlist_unsupp,
	.fill_elf_slot = aie2_cmdlist_unsupp,
	.get_chain_msg_op = aie2_get_chain_msg_op,
};

@@ -680,6 +695,74 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
	return 0;
}

static int
aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
{
	struct cmd_chain_slot_npu *npu_slot = slot;
	struct amdxdna_cmd_preempt_data *pd;
	u32 cmd_len;
	u32 arg_sz;

	pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
	arg_sz = cmd_len - sizeof(*pd);
	if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
		return -EINVAL;

	if (*size < sizeof(*npu_slot) + arg_sz)
		return -EINVAL;

	npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
	if (npu_slot->cu_idx == INVALID_CU_IDX)
		return -EINVAL;

	memset(npu_slot, 0, sizeof(*npu_slot));
	npu_slot->type = EXEC_NPU_TYPE_PREEMPT;
	npu_slot->inst_buf_addr = pd->inst_buf;
	npu_slot->save_buf_addr = pd->save_buf;
	npu_slot->restore_buf_addr = pd->restore_buf;
	npu_slot->inst_size = pd->inst_size;
	npu_slot->save_size = pd->save_size;
	npu_slot->restore_size = pd->restore_size;
	npu_slot->inst_prop_cnt = pd->inst_prop_cnt;
	npu_slot->arg_cnt = arg_sz / sizeof(u32);
	memcpy(npu_slot->args, pd->prop_args, arg_sz);

	*size = sizeof(*npu_slot) + arg_sz;
	return 0;
}

static int
aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
{
	struct cmd_chain_slot_npu *npu_slot = slot;
	struct amdxdna_cmd_preempt_data *pd;
	u32 cmd_len;
	u32 arg_sz;

	pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
	arg_sz = cmd_len - sizeof(*pd);
	if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
		return -EINVAL;

	if (*size < sizeof(*npu_slot) + arg_sz)
		return -EINVAL;

	memset(npu_slot, 0, sizeof(*npu_slot));
	npu_slot->type = EXEC_NPU_TYPE_ELF;
	npu_slot->inst_buf_addr = pd->inst_buf;
	npu_slot->save_buf_addr = pd->save_buf;
	npu_slot->restore_buf_addr = pd->restore_buf;
	npu_slot->inst_size = pd->inst_size;
	npu_slot->save_size = pd->save_size;
	npu_slot->restore_size = pd->restore_size;
	npu_slot->inst_prop_cnt = pd->inst_prop_cnt;
	npu_slot->arg_cnt = 1;
	npu_slot->args[0] = AIE2_EXEC_BUFFER_KERNEL_OP_TXN;

	*size = struct_size(npu_slot, args, npu_slot->arg_cnt);
	return 0;
}

static u32 aie2_get_npu_chain_msg_op(u32 cmd_op)
{
	return MSG_OP_CHAIN_EXEC_NPU;
@@ -691,6 +774,8 @@ static struct aie2_exec_msg_ops npu_exec_message_ops = {
	.init_chain_req = aie2_init_npu_chain_req,
	.fill_cf_slot = aie2_cmdlist_fill_npu_cf,
	.fill_dpu_slot = aie2_cmdlist_fill_npu_dpu,
	.fill_preempt_slot = aie2_cmdlist_fill_npu_preempt,
	.fill_elf_slot = aie2_cmdlist_fill_npu_elf,
	.get_chain_msg_op = aie2_get_npu_chain_msg_op,
};

@@ -749,6 +834,16 @@ aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo,
	case ERT_START_NPU:
		ret = EXEC_MSG_OPS(xdna)->fill_dpu_slot(cmd_abo, slot, size);
		break;
	case ERT_START_NPU_PREEMPT:
		if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT))
			return -EOPNOTSUPP;
		ret = EXEC_MSG_OPS(xdna)->fill_preempt_slot(cmd_abo, slot, size);
		break;
	case ERT_START_NPU_PREEMPT_ELF:
		if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT))
			return -EOPNOTSUPP;
		ret = EXEC_MSG_OPS(xdna)->fill_elf_slot(cmd_abo, slot, size);
		break;
	default:
		XDNA_INFO(xdna, "Unsupported op %d", op);
		ret = -EOPNOTSUPP;
Loading