drivers/media/platform/verisilicon/hantro_postproc.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/verisilicon/hantro_postproc.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/verisilicon/hantro_postproc.c
Extension
.c
Size
9843 bytes
Lines
345
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 (priv->cpu) {
			dma_free_attrs(vpu->dev, priv->size, priv->cpu,
				       priv->dma, priv->attrs);
			priv->cpu = NULL;
		}
	}
}

static unsigned int hantro_postproc_buffer_size(struct hantro_ctx *ctx)
{
	unsigned int buf_size;

	buf_size = ctx->ref_fmt.plane_fmt[0].sizeimage;
	if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
		buf_size += hantro_h264_mv_size(ctx->ref_fmt.width,
						ctx->ref_fmt.height);
	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME)
		buf_size += hantro_vp9_mv_size(ctx->ref_fmt.width,
					       ctx->ref_fmt.height);
	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) {
		buf_size += hantro_hevc_mv_size(ctx->ref_fmt.width,
						ctx->ref_fmt.height);
		if (ctx->hevc_dec.use_compression)
			buf_size += hantro_hevc_compressed_size(ctx->ref_fmt.width,
								ctx->ref_fmt.height);
	}
	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME)
		buf_size += hantro_av1_mv_size(ctx->ref_fmt.width,
					       ctx->ref_fmt.height);

	return buf_size;
}

static int hantro_postproc_alloc(struct hantro_ctx *ctx, int index)
{
	struct hantro_dev *vpu = ctx->dev;
	struct hantro_aux_buf *priv = &ctx->postproc.dec_q[index];
	unsigned int buf_size = hantro_postproc_buffer_size(ctx);

	if (!buf_size)
		return -EINVAL;

	/*
	 * The buffers on this queue are meant as intermediate
	 * buffers for the decoder, so no mapping is needed.
	 */
	priv->attrs = DMA_ATTR_NO_KERNEL_MAPPING;
	priv->cpu = dma_alloc_attrs(vpu->dev, buf_size, &priv->dma,
				    GFP_KERNEL, priv->attrs);
	if (!priv->cpu)
		return -ENOMEM;
	priv->size = buf_size;

	return 0;
}

int hantro_postproc_init(struct hantro_ctx *ctx)
{
	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
	struct vb2_queue *cap_queue = &m2m_ctx->cap_q_ctx.q;
	unsigned int num_buffers = vb2_get_num_buffers(cap_queue);
	unsigned int i;
	int ret;

	for (i = 0; i < num_buffers; i++) {
		ret = hantro_postproc_alloc(ctx, i);
		if (ret) {
			hantro_postproc_free(ctx);
			return ret;
		}
	}

	return 0;
}

dma_addr_t
hantro_postproc_get_dec_buf_addr(struct hantro_ctx *ctx, int index)
{
	struct hantro_aux_buf *priv = &ctx->postproc.dec_q[index];
	unsigned int buf_size = hantro_postproc_buffer_size(ctx);
	struct hantro_dev *vpu = ctx->dev;
	int ret;

	if (priv->size < buf_size && priv->cpu) {
		/* buffer is too small, release it */
		dma_free_attrs(vpu->dev, priv->size, priv->cpu,
			       priv->dma, priv->attrs);
		priv->cpu = NULL;
	}

Annotation

Implementation Notes