drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
Extension
.c
Size
20247 bytes
Lines
739
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 (ret == 0) {
			dev_err(&ctx->mdp_dev->pdev->dev,
				"%d jobs not yet done\n",
				refcount_read(&ctx->mdp_dev->job_count));
			goto worker_end;
		}
	}

	ret = mdp_cmdq_send(ctx->mdp_dev, &task);
	if (ret) {
		dev_err(&ctx->mdp_dev->pdev->dev,
			"CMDQ sendtask failed: %d\n", ret);
		goto worker_end;
	}

	return;

worker_end:
	mdp_m2m_process_done(ctx, vb_state);
}

static int mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(q);
	struct mdp_frame *capture;
	struct vb2_queue *vq;
	int ret;
	bool out_streaming, cap_streaming;

	if (V4L2_TYPE_IS_OUTPUT(q->type))
		ctx->frame_count[MDP_M2M_SRC] = 0;

	if (V4L2_TYPE_IS_CAPTURE(q->type))
		ctx->frame_count[MDP_M2M_DST] = 0;

	capture = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
	vq = v4l2_m2m_get_src_vq(ctx->m2m_ctx);
	out_streaming = vb2_is_streaming(vq);
	vq = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
	cap_streaming = vb2_is_streaming(vq);

	/* Check to see if scaling ratio is within supported range */
	if ((V4L2_TYPE_IS_OUTPUT(q->type) && cap_streaming) ||
	    (V4L2_TYPE_IS_CAPTURE(q->type) && out_streaming)) {
		ret = mdp_check_scaling_ratio(&capture->crop.c,
					      &capture->compose,
					      capture->rotation,
					      ctx->curr_param.limit);
		if (ret) {
			dev_err(&ctx->mdp_dev->pdev->dev,
				"Out of scaling range\n");
			return ret;
		}
	}

	if (!mdp_m2m_ctx_is_state_set(ctx, MDP_VPU_INIT)) {
		ret = mdp_vpu_get_locked(ctx->mdp_dev);
		if (ret) {
			dev_err(&ctx->mdp_dev->pdev->dev,
				"VPU init failed %d\n", ret);
			return -EINVAL;
		}
		mdp_m2m_ctx_set_state(ctx, MDP_VPU_INIT);
	}

	return 0;
}

static struct vb2_v4l2_buffer *mdp_m2m_buf_remove(struct mdp_m2m_ctx *ctx,
						  unsigned int type)
{
	if (V4L2_TYPE_IS_OUTPUT(type))
		return (struct vb2_v4l2_buffer *)
			v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
	else
		return (struct vb2_v4l2_buffer *)
			v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
}

static void mdp_m2m_stop_streaming(struct vb2_queue *q)
{
	struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(q);
	struct vb2_v4l2_buffer *vb;

	vb = mdp_m2m_buf_remove(ctx, q->type);
	while (vb) {
		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
		vb = mdp_m2m_buf_remove(ctx, q->type);
	}
}

Annotation

Implementation Notes