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

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
...@@ -112,7 +112,7 @@ const struct rockchip_vpu_variant rk3288_vpu_variant = { ...@@ -112,7 +112,7 @@ const struct rockchip_vpu_variant rk3288_vpu_variant = {
.enc_fmts = rk3288_vpu_enc_fmts, .enc_fmts = rk3288_vpu_enc_fmts,
.num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts), .num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts),
.codec_ops = rk3288_vpu_codec_ops, .codec_ops = rk3288_vpu_codec_ops,
.codec = RK_VPU_CODEC_JPEG, .codec = RK_VPU_JPEG_ENCODER,
.vepu_irq = rk3288_vepu_irq, .vepu_irq = rk3288_vepu_irq,
.init = rk3288_vpu_hw_init, .init = rk3288_vpu_hw_init,
.clk_names = {"aclk", "hclk"}, .clk_names = {"aclk", "hclk"},
......
...@@ -111,7 +111,7 @@ const struct rockchip_vpu_variant rk3399_vpu_variant = { ...@@ -111,7 +111,7 @@ const struct rockchip_vpu_variant rk3399_vpu_variant = {
.enc_offset = 0x0, .enc_offset = 0x0,
.enc_fmts = rk3399_vpu_enc_fmts, .enc_fmts = rk3399_vpu_enc_fmts,
.num_enc_fmts = ARRAY_SIZE(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, .codec_ops = rk3399_vpu_codec_ops,
.vepu_irq = rk3399_vepu_irq, .vepu_irq = rk3399_vepu_irq,
.init = rk3399_vpu_hw_init, .init = rk3399_vpu_hw_init,
......
...@@ -34,7 +34,10 @@ ...@@ -34,7 +34,10 @@
struct rockchip_vpu_ctx; struct rockchip_vpu_ctx;
struct rockchip_vpu_codec_ops; 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 * struct rockchip_vpu_variant - information about VPU hardware variant
...@@ -79,6 +82,18 @@ enum rockchip_vpu_codec_mode { ...@@ -79,6 +82,18 @@ enum rockchip_vpu_codec_mode {
RK_VPU_MODE_JPEG_ENC, 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 * struct rockchip_vpu_func - rockchip VPU functionality
* *
......
...@@ -245,22 +245,51 @@ static const struct v4l2_ctrl_ops rockchip_vpu_ctrl_ops = { ...@@ -245,22 +245,51 @@ static const struct v4l2_ctrl_ops rockchip_vpu_ctrl_ops = {
.s_ctrl = rockchip_vpu_s_ctrl, .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, 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); int i, num_ctrls = ARRAY_SIZE(controls);
if (vpu->variant->codec & RK_VPU_CODEC_JPEG) {
v4l2_ctrl_new_std(&ctx->ctrl_handler, &rockchip_vpu_ctrl_ops, v4l2_ctrl_handler_init(&ctx->ctrl_handler, num_ctrls);
V4L2_CID_JPEG_COMPRESSION_QUALITY,
5, 100, 1, 50); 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) { 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); ctx->ctrl_handler.error);
v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_ctrl_handler_free(&ctx->ctrl_handler);
return ctx->ctrl_handler.error; return ctx->ctrl_handler.error;
} }
} }
return v4l2_ctrl_handler_setup(&ctx->ctrl_handler); return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
} }
...@@ -274,7 +303,7 @@ static int rockchip_vpu_open(struct file *filp) ...@@ -274,7 +303,7 @@ static int rockchip_vpu_open(struct file *filp)
struct video_device *vdev = video_devdata(filp); struct video_device *vdev = video_devdata(filp);
struct rockchip_vpu_func *func = rockchip_vpu_vdev_to_func(vdev); struct rockchip_vpu_func *func = rockchip_vpu_vdev_to_func(vdev);
struct rockchip_vpu_ctx *ctx; struct rockchip_vpu_ctx *ctx;
int ret; int allowed_codecs, ret;
/* /*
* We do not need any extra locking here, because we operate only * We do not need any extra locking here, because we operate only
...@@ -291,10 +320,12 @@ static int rockchip_vpu_open(struct file *filp) ...@@ -291,10 +320,12 @@ static int rockchip_vpu_open(struct file *filp)
ctx->dev = vpu; ctx->dev = vpu;
if (func->id == MEDIA_ENT_F_PROC_VIDEO_ENCODER) { 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->buf_finish = rockchip_vpu_enc_buf_finish;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx, ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
queue_init); queue_init);
} else if (func->id == MEDIA_ENT_F_PROC_VIDEO_DECODER) { } 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->buf_finish = rockchip_vpu_dec_buf_finish;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx, ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
queue_init); queue_init);
...@@ -313,7 +344,7 @@ static int rockchip_vpu_open(struct file *filp) ...@@ -313,7 +344,7 @@ static int rockchip_vpu_open(struct file *filp)
rockchip_vpu_reset_fmts(ctx); rockchip_vpu_reset_fmts(ctx);
ret = rockchip_vpu_ctrls_setup(vpu, ctx); ret = rockchip_vpu_ctrls_setup(vpu, ctx, allowed_codecs);
if (ret) { if (ret) {
vpu_err("Failed to set up controls\n"); vpu_err("Failed to set up controls\n");
goto err_fh_free; goto err_fh_free;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment