drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
Extension
.c
Size
76153 bytes
Lines
2758
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 (!list_empty(&ctx->dst_queue)) {
			dst_mb = list_entry(ctx->dst_queue.next,
					struct s5p_mfc_buf, list);
			list_del(&dst_mb->list);
			ctx->dst_queue_cnt--;
			vb2_set_plane_payload(&dst_mb->b->vb2_buf, 0,
				s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size,
						dev));
			vb2_buffer_done(&dst_mb->b->vb2_buf,
					VB2_BUF_STATE_DONE);
		}
	}

	if (!IS_MFCV6_PLUS(dev)) {
		ctx->state = MFCINST_RUNNING;
		if (s5p_mfc_ctx_ready(ctx))
			set_work_bit_irqsave(ctx);
		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
	} else {
		ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_enc_dpb_count, dev);
		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
					get_e_min_scratch_buf_size, dev);
			if (!IS_MFCV12(dev))
				ctx->bank1.size += ctx->scratch_buf_size;
		}
		ctx->state = MFCINST_HEAD_PRODUCED;
	}

	return 0;
}

static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_dev *dev = ctx->dev;
	struct s5p_mfc_buf *dst_mb;
	struct s5p_mfc_buf *src_mb;
	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
	unsigned int dst_size;

	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc ==
			V4L2_PIX_FMT_YVU420M)
		src_c_1_addr =
			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
	else
		src_c_1_addr = 0;
	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
					src_y_addr, src_c_addr, src_c_1_addr);

	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
	dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
	s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
			dst_size);

	return 0;
}

static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_dev *dev = ctx->dev;
	struct s5p_mfc_buf *mb_entry;
	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
	int slice_type;
	unsigned int strm_size;
	bool src_ready;

	slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
	strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
	mfc_debug(2, "Encoded slice type: %d\n", slice_type);
	mfc_debug(2, "Encoded stream size: %d\n", strm_size);
	mfc_debug(2, "Display order: %d\n",
		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
	if (slice_type >= 0) {
		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
			mb_y_addr = vb2_dma_contig_plane_dma_addr(
					&mb_entry->b->vb2_buf, 0);
			mb_c_addr = vb2_dma_contig_plane_dma_addr(
					&mb_entry->b->vb2_buf, 1);
			if (ctx->src_fmt->fourcc ==
					V4L2_PIX_FMT_YUV420M ||
					ctx->src_fmt->fourcc ==
					V4L2_PIX_FMT_YVU420M)
				mb_c_1_addr = vb2_dma_contig_plane_dma_addr

Annotation

Implementation Notes