drivers/media/platform/chips-media/coda/imx-vdoa.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/chips-media/coda/imx-vdoa.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/chips-media/coda/imx-vdoa.c
Extension
.c
Size
7899 bytes
Lines
347
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 vdoa_data {
	struct vdoa_ctx		*curr_ctx;
	struct device		*dev;
	struct clk		*vdoa_clk;
	void __iomem		*regs;
};

struct vdoa_q_data {
	unsigned int	width;
	unsigned int	height;
	unsigned int	bytesperline;
	unsigned int	sizeimage;
	u32		pixelformat;
};

struct vdoa_ctx {
	struct vdoa_data	*vdoa;
	struct completion	completion;
	struct vdoa_q_data	q_data[2];
	unsigned int		submitted_job;
	unsigned int		completed_job;
};

static irqreturn_t vdoa_irq_handler(int irq, void *data)
{
	struct vdoa_data *vdoa = data;
	struct vdoa_ctx *curr_ctx;
	u32 val;

	/* Disable interrupts */
	writel(0, vdoa->regs + VDOAIE);

	curr_ctx = vdoa->curr_ctx;
	if (!curr_ctx) {
		dev_warn(vdoa->dev,
			"Instance released before the end of transaction\n");
		return IRQ_HANDLED;
	}

	val = readl(vdoa->regs + VDOAIST);
	writel(val, vdoa->regs + VDOAIST);
	if (val & VDOAIST_TERR) {
		val = readl(vdoa->regs + VDOASR) & VDOASR_ERRW;
		dev_err(vdoa->dev, "AXI %s error\n", val ? "write" : "read");
	} else if (!(val & VDOAIST_EOT)) {
		dev_warn(vdoa->dev, "Spurious interrupt\n");
	}
	curr_ctx->completed_job++;
	complete(&curr_ctx->completion);

	return IRQ_HANDLED;
}

int vdoa_wait_for_completion(struct vdoa_ctx *ctx)
{
	struct vdoa_data *vdoa = ctx->vdoa;

	if (ctx->submitted_job == ctx->completed_job)
		return 0;

	if (!wait_for_completion_timeout(&ctx->completion,
					 msecs_to_jiffies(300))) {
		dev_err(vdoa->dev,
			"Timeout waiting for transfer result\n");
		return -ETIMEDOUT;
	}

	return 0;
}
EXPORT_SYMBOL(vdoa_wait_for_completion);

void vdoa_device_run(struct vdoa_ctx *ctx, dma_addr_t dst, dma_addr_t src)
{
	struct vdoa_q_data *src_q_data, *dst_q_data;
	struct vdoa_data *vdoa = ctx->vdoa;
	u32 val;

	if (vdoa->curr_ctx)
		vdoa_wait_for_completion(vdoa->curr_ctx);

	vdoa->curr_ctx = ctx;

	reinit_completion(&ctx->completion);
	ctx->submitted_job++;

	src_q_data = &ctx->q_data[V4L2_M2M_SRC];
	dst_q_data = &ctx->q_data[V4L2_M2M_DST];

	/* Progressive, no sync, 1 frame per run */
	if (dst_q_data->pixelformat == V4L2_PIX_FMT_YUYV)

Annotation

Implementation Notes