drivers/media/platform/nvidia/tegra-vde/v4l2.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/nvidia/tegra-vde/v4l2.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/nvidia/tegra-vde/v4l2.c
Extension
.c
Size
25768 bytes
Lines
1015
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 (ctx->ctrls[i]->id == id) {
			tegra_set_control_data(ctx, ctx->ctrls[i]->p_cur.p, id);
			return;
		}
	}

	tegra_set_control_data(ctx, NULL, id);
}

static int tegra_queue_setup(struct vb2_queue *vq,
			     unsigned int *nbufs,
			     unsigned int *num_planes,
			     unsigned int sizes[],
			     struct device *alloc_devs[])
{
	struct tegra_ctx *ctx = vb2_get_drv_priv(vq);
	struct v4l2_format *f;
	unsigned int i;

	if (V4L2_TYPE_IS_OUTPUT(vq->type))
		f = &ctx->coded_fmt;
	else
		f = &ctx->decoded_fmt;

	if (*num_planes) {
		if (*num_planes != f->fmt.pix_mp.num_planes)
			return -EINVAL;

		for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
			if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage)
				return -EINVAL;
		}
	} else {
		*num_planes = f->fmt.pix_mp.num_planes;

		for (i = 0; i < f->fmt.pix_mp.num_planes; i++)
			sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage;
	}

	return 0;
}

static int tegra_buf_out_validate(struct vb2_buffer *vb)
{
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);

	vbuf->field = V4L2_FIELD_NONE;
	return 0;
}

static void __tegra_buf_cleanup(struct vb2_buffer *vb, unsigned int i)
{
	struct vb2_queue *vq = vb->vb2_queue;
	struct tegra_ctx *ctx = vb2_get_drv_priv(vq);
	struct tegra_m2m_buffer *tb = vb_to_tegra_buf(vb);

	while (i--) {
		if (tb->a[i]) {
			tegra_vde_dmabuf_cache_unmap(ctx->vde, tb->a[i], true);
			tb->a[i] = NULL;
		}

		if (tb->iova[i]) {
			tegra_vde_iommu_unmap(ctx->vde, tb->iova[i]);
			tb->iova[i] = NULL;
		}
	}

	if (tb->aux) {
		tegra_vde_free_bo(tb->aux);
		tb->aux = NULL;
	}
}

static int tegra_buf_init(struct vb2_buffer *vb)
{
	struct vb2_queue *vq = vb->vb2_queue;
	struct tegra_ctx *ctx = vb2_get_drv_priv(vq);
	struct tegra_m2m_buffer *tb = vb_to_tegra_buf(vb);
	struct tegra_vde *vde = ctx->vde;
	enum dma_data_direction dma_dir;
	struct sg_table *sgt;
	unsigned int i;
	int err;

	if (V4L2_TYPE_IS_CAPTURE(vq->type) && vb->num_planes > 1) {
		/*
		 * Tegra decoder writes auxiliary data for I/P frames.
		 * This data is needed for decoding of B frames.
		 */

Annotation

Implementation Notes