drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c
Extension
.c
Size
3939 bytes
Lines
180
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 rkvdec_rcb_config {
	struct rkvdec_aux_buf *rcb_bufs;
	size_t rcb_count;
};

static size_t rkvdec_rcb_size(const struct rcb_size_info *size_info,
			      unsigned int width, unsigned int height)
{
	return size_info->multiplier * (size_info->axis == PIC_HEIGHT ? height : width);
}

dma_addr_t rkvdec_rcb_buf_dma_addr(struct rkvdec_ctx *ctx, int id)
{
	return ctx->rcb_config->rcb_bufs[id].dma;
}

size_t rkvdec_rcb_buf_size(struct rkvdec_ctx *ctx, int id)
{
	return ctx->rcb_config->rcb_bufs[id].size;
}

int rkvdec_rcb_buf_count(struct rkvdec_ctx *ctx)
{
	return ctx->rcb_config->rcb_count;
}

void rkvdec_free_rcb(struct rkvdec_ctx *ctx)
{
	struct rkvdec_dev *dev = ctx->dev;
	struct rkvdec_rcb_config *cfg = ctx->rcb_config;
	unsigned long virt_addr;
	int i;

	if (!cfg)
		return;

	for (i = 0; i < cfg->rcb_count; i++) {
		size_t rcb_size = cfg->rcb_bufs[i].size;

		if (!cfg->rcb_bufs[i].cpu)
			continue;

		switch (cfg->rcb_bufs[i].type) {
		case RKVDEC_ALLOC_SRAM:
			virt_addr = (unsigned long)cfg->rcb_bufs[i].cpu;

			if (dev->iommu_domain)
				iommu_unmap(dev->iommu_domain, virt_addr, rcb_size);
			gen_pool_free(dev->sram_pool, virt_addr, rcb_size);
			break;
		case RKVDEC_ALLOC_DMA:
			dma_free_coherent(dev->dev,
					  rcb_size,
					  cfg->rcb_bufs[i].cpu,
					  cfg->rcb_bufs[i].dma);
			break;
		}
	}

	if (cfg->rcb_bufs)
		devm_kfree(dev->dev, cfg->rcb_bufs);

	devm_kfree(dev->dev, cfg);
}

int rkvdec_allocate_rcb(struct rkvdec_ctx *ctx,
			const struct rcb_size_info *size_info,
			size_t rcb_count)
{
	int ret, i;
	u32 width, height;
	struct rkvdec_dev *rkvdec = ctx->dev;
	struct rkvdec_rcb_config *cfg;

	if (!size_info || !rcb_count) {
		ctx->rcb_config = NULL;
		return 0;
	}

	ctx->rcb_config = devm_kzalloc(rkvdec->dev, sizeof(*ctx->rcb_config), GFP_KERNEL);
	if (!ctx->rcb_config)
		return -ENOMEM;

	cfg = ctx->rcb_config;

	cfg->rcb_bufs = devm_kzalloc(rkvdec->dev, sizeof(*cfg->rcb_bufs) * rcb_count, GFP_KERNEL);
	if (!cfg->rcb_bufs) {
		ret = -ENOMEM;
		goto err_alloc;
	}

Annotation

Implementation Notes