Commit 4cb3a0f3 authored by Tomi Valkeinen's avatar Tomi Valkeinen Committed by Mauro Carvalho Chehab
Browse files

media: ti-vpe: cal: allocate pix proc dynamically



CAL has 4 pixel processing units but the units are not needed e.g. for
metadata. As we could be capturing 4 pixel streams and 4 metadata
streams, i.e. using 8 DMA contexts, we cannot assign a pixel processing
unit to every DMA context. Instead we need to reserve a pixel processing
unit only when needed.

Add functions to reserve and release a pix proc unit, and use them in
cal_ctx_prepare/unprepare. Note that for the time being we still always
reserve a pix proc unit.

Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 38f7435f
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -290,6 +290,37 @@ void cal_quickdump_regs(struct cal_dev *cal)
 * ------------------------------------------------------------------
 */

#define CAL_MAX_PIX_PROC 4

static int cal_reserve_pix_proc(struct cal_dev *cal)
{
	unsigned long ret;

	spin_lock(&cal->v4l2_dev.lock);

	ret = find_first_zero_bit(&cal->reserved_pix_proc_mask, CAL_MAX_PIX_PROC);

	if (ret == CAL_MAX_PIX_PROC) {
		spin_unlock(&cal->v4l2_dev.lock);
		return -ENOSPC;
	}

	cal->reserved_pix_proc_mask |= BIT(ret);

	spin_unlock(&cal->v4l2_dev.lock);

	return ret;
}

static void cal_release_pix_proc(struct cal_dev *cal, unsigned int pix_proc_num)
{
	spin_lock(&cal->v4l2_dev.lock);

	cal->reserved_pix_proc_mask &= ~BIT(pix_proc_num);

	spin_unlock(&cal->v4l2_dev.lock);
}

static void cal_ctx_csi2_config(struct cal_ctx *ctx)
{
	u32 val;
@@ -433,11 +464,22 @@ static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)

int cal_ctx_prepare(struct cal_ctx *ctx)
{
	int ret;

	ret = cal_reserve_pix_proc(ctx->cal);
	if (ret < 0) {
		ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret);
		return ret;
	}

	ctx->pix_proc = ret;

	return 0;
}

void cal_ctx_unprepare(struct cal_ctx *ctx)
{
	cal_release_pix_proc(ctx->cal, ctx->pix_proc);
}

void cal_ctx_start(struct cal_ctx *ctx)
@@ -872,7 +914,6 @@ static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
	ctx->dma_ctx = inst;
	ctx->csi2_ctx = inst;
	ctx->cport = inst;
	ctx->pix_proc = inst;

	ret = cal_ctx_v4l2_init(ctx);
	if (ret)
+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,8 @@ struct cal_dev {
	struct media_device	mdev;
	struct v4l2_device	v4l2_dev;
	struct v4l2_async_notifier notifier;

	unsigned long		reserved_pix_proc_mask;
};

/*