drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
Extension
.c
Size
33461 bytes
Lines
997
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

struct hantro_vp9_ref_reg {
	const struct hantro_reg width;
	const struct hantro_reg height;
	const struct hantro_reg hor_scale;
	const struct hantro_reg ver_scale;
	u32 y_base;
	u32 c_base;
};

static void config_ref(struct hantro_ctx *ctx,
		       struct hantro_decoded_buffer *dst,
		       const struct hantro_vp9_ref_reg *ref_reg,
		       const struct v4l2_ctrl_vp9_frame *dec_params,
		       u64 ref_ts)
{
	struct hantro_decoded_buffer *buf;
	dma_addr_t luma_addr, chroma_addr;
	u32 refw, refh;

	buf = get_ref_buf(ctx, &dst->base.vb, ref_ts);
	refw = buf->vp9.width;
	refh = buf->vp9.height;

	hantro_reg_write(ctx->dev, &ref_reg->width, refw);
	hantro_reg_write(ctx->dev, &ref_reg->height, refh);

	hantro_reg_write(ctx->dev, &ref_reg->hor_scale, (refw << 14) / dst->vp9.width);
	hantro_reg_write(ctx->dev, &ref_reg->ver_scale, (refh << 14) / dst->vp9.height);

	luma_addr = hantro_get_dec_buf_addr(ctx, &buf->base.vb.vb2_buf);
	hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr);

	chroma_addr = luma_addr + buf->vp9.chroma_offset;
	hantro_write_addr(ctx->dev, ref_reg->c_base, chroma_addr);
}

static void config_ref_registers(struct hantro_ctx *ctx,
				 const struct v4l2_ctrl_vp9_frame *dec_params,
				 struct hantro_decoded_buffer *dst,
				 struct hantro_decoded_buffer *mv_ref)
{
	static const struct hantro_vp9_ref_reg ref_regs[] = {
		{
			/* Last */
			.width = vp9_lref_width,
			.height = vp9_lref_height,
			.hor_scale = vp9_lref_hor_scale,
			.ver_scale = vp9_lref_ver_scale,
			.y_base = G2_REF_LUMA_ADDR(0),
			.c_base = G2_REF_CHROMA_ADDR(0),
		}, {
			/* Golden */
			.width = vp9_gref_width,
			.height = vp9_gref_height,
			.hor_scale = vp9_gref_hor_scale,
			.ver_scale = vp9_gref_ver_scale,
			.y_base = G2_REF_LUMA_ADDR(4),
			.c_base = G2_REF_CHROMA_ADDR(4),
		}, {
			/* Altref */
			.width = vp9_aref_width,
			.height = vp9_aref_height,
			.hor_scale = vp9_aref_hor_scale,
			.ver_scale = vp9_aref_ver_scale,
			.y_base = G2_REF_LUMA_ADDR(5),
			.c_base = G2_REF_CHROMA_ADDR(5),
		},
	};
	dma_addr_t mv_addr;

	config_ref(ctx, dst, &ref_regs[0], dec_params, dec_params->last_frame_ts);
	config_ref(ctx, dst, &ref_regs[1], dec_params, dec_params->golden_frame_ts);
	config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts);

	mv_addr = hantro_get_dec_buf_addr(ctx, &mv_ref->base.vb.vb2_buf) +
		  mv_ref->vp9.mv_offset;
	hantro_write_addr(ctx->dev, G2_REF_MV_ADDR(0), mv_addr);

	hantro_reg_write(ctx->dev, &vp9_last_sign_bias,
			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_LAST ? 1 : 0);

	hantro_reg_write(ctx->dev, &vp9_gref_sign_bias,
			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_GOLDEN ? 1 : 0);

	hantro_reg_write(ctx->dev, &vp9_aref_sign_bias,
			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_ALT ? 1 : 0);
}

static void recompute_tile_info(unsigned short *tile_info, unsigned int tiles, unsigned int sbs)
{

Annotation

Implementation Notes