drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
Extension
.c
Size
7960 bytes
Lines
317
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
			ret = true;
			break;
		}
	}
	spin_unlock_irqrestore(&dec_dev->dev_ctx_lock, flags);

	return ret;
}

/*
 * vpu_dec_ipi_handler - Handler for VPU ipi message.
 *
 * @data: ipi message
 * @len : length of ipi message
 * @priv: callback private data which is passed by decoder when register.
 *
 * This function runs in interrupt context and it means there's an IPI MSG
 * from VPU.
 */
static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
{
	struct mtk_vcodec_dec_dev *dec_dev;
	const struct vdec_vpu_ipi_ack *msg = data;
	struct vdec_vpu_inst *vpu;

	dec_dev = (struct mtk_vcodec_dec_dev *)priv;
	vpu = (struct vdec_vpu_inst *)(unsigned long)msg->ap_inst_addr;
	if (!priv || !vpu) {
		pr_err(MTK_DBG_V4L2_STR "ap_inst_addr is NULL, did the SCP hang or crash?");
		return;
	}

	if (!vpu_dec_check_ap_inst(dec_dev, vpu) || msg->msg_id < VPU_IPIMSG_DEC_INIT_ACK ||
	    msg->msg_id > VPU_IPIMSG_DEC_GET_PARAM_ACK) {
		mtk_v4l2_vdec_err(vpu->ctx, "vdec msg id not correctly => 0x%x", msg->msg_id);
		vpu->failure = -EINVAL;
		goto error;
	}

	vpu->failure = msg->status;
	if (msg->status != 0)
		goto error;

	switch (msg->msg_id) {
	case VPU_IPIMSG_DEC_INIT_ACK:
		handle_init_ack_msg(data);
		break;

	case VPU_IPIMSG_DEC_START_ACK:
	case VPU_IPIMSG_DEC_END_ACK:
	case VPU_IPIMSG_DEC_DEINIT_ACK:
	case VPU_IPIMSG_DEC_RESET_ACK:
	case VPU_IPIMSG_DEC_CORE_ACK:
	case VPU_IPIMSG_DEC_CORE_END_ACK:
		break;

	case VPU_IPIMSG_DEC_GET_PARAM_ACK:
		handle_get_param_msg_ack(data);
		break;
	default:
		mtk_vdec_err(vpu->ctx, "invalid msg=%X", msg->msg_id);
		break;
	}

error:
	vpu->signaled = 1;
}

static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
{
	int err, id, msgid;

	msgid = *(uint32_t *)msg;
	mtk_vdec_debug(vpu->ctx, "id=%X", msgid);

	vpu->failure = 0;
	vpu->signaled = 0;

	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
		if (msgid == AP_IPIMSG_DEC_CORE ||
		    msgid == AP_IPIMSG_DEC_CORE_END)
			id = vpu->core_id;
		else
			id = vpu->id;
	} else {
		id = vpu->id;
	}

	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,

Annotation

Implementation Notes