Commit 6d9a39cf authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Mauro Carvalho Chehab
Browse files

media: rockchip/vpu: Add support for non-standard controls



Rework the way controls are registered by the driver,
so it can support non-standard controls, such as those
used by stateless codecs.

Signed-off-by: default avatarEzequiel Garcia <ezequiel@collabora.com>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 8c3dc73d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ const struct rockchip_vpu_variant rk3288_vpu_variant = {
	.enc_fmts = rk3288_vpu_enc_fmts,
	.num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts),
	.codec_ops = rk3288_vpu_codec_ops,
	.codec = RK_VPU_CODEC_JPEG,
	.codec = RK_VPU_JPEG_ENCODER,
	.vepu_irq = rk3288_vepu_irq,
	.init = rk3288_vpu_hw_init,
	.clk_names = {"aclk", "hclk"},
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ const struct rockchip_vpu_variant rk3399_vpu_variant = {
	.enc_offset = 0x0,
	.enc_fmts = rk3399_vpu_enc_fmts,
	.num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts),
	.codec = RK_VPU_CODEC_JPEG,
	.codec = RK_VPU_JPEG_ENCODER,
	.codec_ops = rk3399_vpu_codec_ops,
	.vepu_irq = rk3399_vepu_irq,
	.init = rk3399_vpu_hw_init,
+16 −1
Original line number Diff line number Diff line
@@ -34,7 +34,10 @@
struct rockchip_vpu_ctx;
struct rockchip_vpu_codec_ops;

#define RK_VPU_CODEC_JPEG BIT(0)
#define RK_VPU_JPEG_ENCODER	BIT(0)
#define RK_VPU_ENCODERS		0x0000ffff

#define RK_VPU_DECODERS		0xffff0000

/**
 * struct rockchip_vpu_variant - information about VPU hardware variant
@@ -79,6 +82,18 @@ enum rockchip_vpu_codec_mode {
	RK_VPU_MODE_JPEG_ENC,
};

/*
 * struct rockchip_vpu_ctrl - helper type to declare supported controls
 * @id:		V4L2 control ID (V4L2_CID_xxx)
 * @codec:	codec id this control belong to (RK_VPU_JPEG_ENCODER, etc.)
 * @cfg:	control configuration
 */
struct rockchip_vpu_ctrl {
	unsigned int id;
	unsigned int codec;
	struct v4l2_ctrl_config cfg;
};

/*
 * struct rockchip_vpu_func - rockchip VPU functionality
 *
+41 −10
Original line number Diff line number Diff line
@@ -245,22 +245,51 @@ static const struct v4l2_ctrl_ops rockchip_vpu_ctrl_ops = {
	.s_ctrl = rockchip_vpu_s_ctrl,
};

static struct rockchip_vpu_ctrl controls[] = {
	{
		.id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
		.codec = RK_VPU_JPEG_ENCODER,
		.cfg = {
			.min = 5,
			.max = 100,
			.step = 1,
			.def = 50,
		},
	},
};

static int rockchip_vpu_ctrls_setup(struct rockchip_vpu_dev *vpu,
				    struct rockchip_vpu_ctx *ctx)
				    struct rockchip_vpu_ctx *ctx,
				    int allowed_codecs)
{
	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
	if (vpu->variant->codec & RK_VPU_CODEC_JPEG) {
		v4l2_ctrl_new_std(&ctx->ctrl_handler, &rockchip_vpu_ctrl_ops,
				  V4L2_CID_JPEG_COMPRESSION_QUALITY,
				  5, 100, 1, 50);
	int i, num_ctrls = ARRAY_SIZE(controls);

	v4l2_ctrl_handler_init(&ctx->ctrl_handler, num_ctrls);

	for (i = 0; i < num_ctrls; i++) {
		if (!(allowed_codecs & controls[i].codec))
			continue;
		if (!controls[i].cfg.elem_size) {
			v4l2_ctrl_new_std(&ctx->ctrl_handler,
					  &rockchip_vpu_ctrl_ops,
					  controls[i].id, controls[i].cfg.min,
					  controls[i].cfg.max,
					  controls[i].cfg.step,
					  controls[i].cfg.def);
		} else {
			controls[i].cfg.id = controls[i].id;
			v4l2_ctrl_new_custom(&ctx->ctrl_handler,
					     &controls[i].cfg, NULL);
		}

		if (ctx->ctrl_handler.error) {
			vpu_err("Adding JPEG control failed %d\n",
			vpu_err("Adding control (%d) failed %d\n",
				controls[i].id,
				ctx->ctrl_handler.error);
			v4l2_ctrl_handler_free(&ctx->ctrl_handler);
			return ctx->ctrl_handler.error;
		}
	}

	return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
}

@@ -274,7 +303,7 @@ static int rockchip_vpu_open(struct file *filp)
	struct video_device *vdev = video_devdata(filp);
	struct rockchip_vpu_func *func = rockchip_vpu_vdev_to_func(vdev);
	struct rockchip_vpu_ctx *ctx;
	int ret;
	int allowed_codecs, ret;

	/*
	 * We do not need any extra locking here, because we operate only
@@ -291,10 +320,12 @@ static int rockchip_vpu_open(struct file *filp)

	ctx->dev = vpu;
	if (func->id == MEDIA_ENT_F_PROC_VIDEO_ENCODER) {
		allowed_codecs = vpu->variant->codec & RK_VPU_ENCODERS;
		ctx->buf_finish = rockchip_vpu_enc_buf_finish;
		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
						    queue_init);
	} else if (func->id == MEDIA_ENT_F_PROC_VIDEO_DECODER) {
		allowed_codecs = vpu->variant->codec & RK_VPU_DECODERS;
		ctx->buf_finish = rockchip_vpu_dec_buf_finish;
		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
						    queue_init);
@@ -313,7 +344,7 @@ static int rockchip_vpu_open(struct file *filp)

	rockchip_vpu_reset_fmts(ctx);

	ret = rockchip_vpu_ctrls_setup(vpu, ctx);
	ret = rockchip_vpu_ctrls_setup(vpu, ctx, allowed_codecs);
	if (ret) {
		vpu_err("Failed to set up controls\n");
		goto err_fh_free;