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

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

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/nvidia/tegra-vde/h264.c
Extension
.c
Size
25546 bytes
Lines
944
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 tegra_vde_h264_decoder_ctx {
	unsigned int dpb_frames_nb;
	unsigned int dpb_ref_frames_with_earlier_poc_nb;
	unsigned int baseline_profile;
	unsigned int level_idc;
	unsigned int log2_max_pic_order_cnt_lsb;
	unsigned int log2_max_frame_num;
	unsigned int pic_order_cnt_type;
	unsigned int direct_8x8_inference_flag;
	unsigned int pic_width_in_mbs;
	unsigned int pic_height_in_mbs;
	unsigned int pic_init_qp;
	unsigned int deblocking_filter_control_present_flag;
	unsigned int constrained_intra_pred_flag;
	unsigned int chroma_qp_index_offset;
	unsigned int pic_order_present_flag;
	unsigned int num_ref_idx_l0_active_minus1;
	unsigned int num_ref_idx_l1_active_minus1;
};

struct h264_reflists {
	struct v4l2_h264_reference p[V4L2_H264_NUM_DPB_ENTRIES];
	struct v4l2_h264_reference b0[V4L2_H264_NUM_DPB_ENTRIES];
	struct v4l2_h264_reference b1[V4L2_H264_NUM_DPB_ENTRIES];
};

static int tegra_vde_wait_mbe(struct tegra_vde *vde)
{
	u32 tmp;

	return readl_relaxed_poll_timeout(vde->mbe + 0x8C, tmp,
					  tmp >= 0x10, 1, 100);
}

static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde,
					 unsigned int refs_nb,
					 bool setup_refs)
{
	u32 value, frame_idx_enb_mask = 0;
	unsigned int frame_idx;
	unsigned int idx;
	int err;

	tegra_vde_writel(vde, 0xD0000000 | (0 << 23), vde->mbe, 0x80);
	tegra_vde_writel(vde, 0xD0200000 | (0 << 23), vde->mbe, 0x80);

	err = tegra_vde_wait_mbe(vde);
	if (err)
		return err;

	if (!setup_refs)
		return 0;

	for (idx = 0, frame_idx = 1; idx < refs_nb; idx++, frame_idx++) {
		tegra_vde_writel(vde, 0xD0000000 | (frame_idx << 23),
				 vde->mbe, 0x80);
		tegra_vde_writel(vde, 0xD0200000 | (frame_idx << 23),
				 vde->mbe, 0x80);

		frame_idx_enb_mask |= frame_idx << (6 * (idx % 4));

		if (idx % 4 == 3 || idx == refs_nb - 1) {
			value = 0xC0000000;
			value |= (idx >> 2) << 24;
			value |= frame_idx_enb_mask;

			tegra_vde_writel(vde, value, vde->mbe, 0x80);

			err = tegra_vde_wait_mbe(vde);
			if (err)
				return err;

			frame_idx_enb_mask = 0;
		}
	}

	return 0;
}

static void tegra_vde_mbe_set_0xa_reg(struct tegra_vde *vde, int reg, u32 val)
{
	tegra_vde_writel(vde, 0xA0000000 | (reg << 24) | (val & 0xFFFF),
			 vde->mbe, 0x80);
	tegra_vde_writel(vde, 0xA0000000 | ((reg + 1) << 24) | (val >> 16),
			 vde->mbe, 0x80);
}

static int tegra_vde_wait_bsev(struct tegra_vde *vde, bool wait_dma)
{
	struct device *dev = vde->dev;

Annotation

Implementation Notes