mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
media: rockchip: ispp: fec to support output size crop by mesh
add rkispp-subdev pad2:Source set format API to support fec crop output size by mesh size. Change-Id: I8857547d1dc07ff033a50b1dc7bc2079a9221b12 Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -139,10 +139,15 @@ static int rkispp_sd_get_fmt(struct v4l2_subdev *sd,
|
||||
ispp_fmt = find_fmt(fmt->format.code);
|
||||
if (!ispp_fmt)
|
||||
goto err;
|
||||
if (ispp_sdev->in_fmt.width != mf->width ||
|
||||
ispp_sdev->in_fmt.height != mf->height) {
|
||||
ispp_sdev->out_fmt = *ispp_fmt;
|
||||
ispp_sdev->out_fmt.width = mf->width;
|
||||
ispp_sdev->out_fmt.height = mf->height;
|
||||
}
|
||||
ispp_sdev->in_fmt = *mf;
|
||||
ispp_sdev->out_fmt = *ispp_fmt;
|
||||
}
|
||||
} else if (fmt->pad == RKISPP_PAD_SOURCE) {
|
||||
} else {
|
||||
*mf = ispp_sdev->in_fmt;
|
||||
mf->width = ispp_sdev->out_fmt.width;
|
||||
mf->height = ispp_sdev->out_fmt.height;
|
||||
@@ -183,87 +188,6 @@ static int rkispp_sd_set_fmt(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkispp_sd_get_selection(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_selection *sel)
|
||||
{
|
||||
struct rkispp_subdev *ispp_sdev = v4l2_get_subdevdata(sd);
|
||||
struct v4l2_rect *crop;
|
||||
int ret = 0;
|
||||
|
||||
if (!sel)
|
||||
goto err;
|
||||
if (sel->pad != RKISPP_PAD_SINK)
|
||||
goto err;
|
||||
|
||||
crop = &sel->r;
|
||||
if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||
if (!cfg)
|
||||
goto err;
|
||||
crop = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
|
||||
}
|
||||
|
||||
if (ispp_sdev->dev->inp != INP_ISP) {
|
||||
crop->left = 0;
|
||||
crop->top = 0;
|
||||
crop->width = ispp_sdev->in_fmt.width;
|
||||
crop->height = ispp_sdev->in_fmt.height;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = v4l2_subdev_call(ispp_sdev->remote_sd,
|
||||
pad, get_selection, cfg, sel);
|
||||
if (!ret && sel->target == V4L2_SEL_TGT_CROP) {
|
||||
ispp_sdev->out_fmt.width = crop->width;
|
||||
ispp_sdev->out_fmt.height = crop->height;
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int rkispp_sd_set_selection(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_selection *sel)
|
||||
{
|
||||
struct rkispp_subdev *ispp_sdev = v4l2_get_subdevdata(sd);
|
||||
struct v4l2_rect *crop;
|
||||
int ret = 0;
|
||||
|
||||
if (!sel)
|
||||
goto err;
|
||||
if (sel->pad != RKISPP_PAD_SINK ||
|
||||
sel->target != V4L2_SEL_TGT_CROP)
|
||||
goto err;
|
||||
|
||||
crop = &sel->r;
|
||||
if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||
if (!cfg)
|
||||
goto err;
|
||||
crop = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
|
||||
}
|
||||
|
||||
if (ispp_sdev->dev->inp != INP_ISP) {
|
||||
crop->left = 0;
|
||||
crop->top = 0;
|
||||
crop->width = ispp_sdev->in_fmt.width;
|
||||
crop->height = ispp_sdev->in_fmt.height;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = v4l2_subdev_call(ispp_sdev->remote_sd,
|
||||
pad, set_selection, cfg, sel);
|
||||
if (!ret) {
|
||||
ispp_sdev->out_fmt.width = crop->width;
|
||||
ispp_sdev->out_fmt.height = crop->height;
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int rkispp_sd_s_stream(struct v4l2_subdev *sd, int on)
|
||||
{
|
||||
struct rkispp_subdev *ispp_sdev = v4l2_get_subdevdata(sd);
|
||||
@@ -338,7 +262,6 @@ static int rkispp_sd_s_power(struct v4l2_subdev *sd, int on)
|
||||
if (on) {
|
||||
if (ispp_dev->inp == INP_ISP) {
|
||||
struct v4l2_subdev_format fmt;
|
||||
struct v4l2_subdev_selection sel;
|
||||
|
||||
/* update format, if ispp input change */
|
||||
fmt.pad = RKISPP_PAD_SINK;
|
||||
@@ -350,17 +273,6 @@ static int rkispp_sd_s_power(struct v4l2_subdev *sd, int on)
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
sel.pad = RKISPP_PAD_SINK;
|
||||
sel.target = V4L2_SEL_TGT_CROP;
|
||||
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
ret = v4l2_subdev_call(sd, pad,
|
||||
get_selection, NULL, &sel);
|
||||
if (ret) {
|
||||
v4l2_err(&ispp_dev->v4l2_dev,
|
||||
"%s get crop fail:%d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = v4l2_subdev_call(ispp_sdev->remote_sd,
|
||||
core, s_power, 1);
|
||||
@@ -507,8 +419,6 @@ static const struct media_entity_operations rkispp_sd_media_ops = {
|
||||
static const struct v4l2_subdev_pad_ops rkispp_sd_pad_ops = {
|
||||
.get_fmt = rkispp_sd_get_fmt,
|
||||
.set_fmt = rkispp_sd_set_fmt,
|
||||
.get_selection = rkispp_sd_get_selection,
|
||||
.set_selection = rkispp_sd_set_selection,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_video_ops rkispp_sd_video_ops = {
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "common.h"
|
||||
#include "params.h"
|
||||
|
||||
#define RKISPP_FEC_BUF_MAX 7
|
||||
|
||||
struct rkispp_stream;
|
||||
|
||||
/*
|
||||
@@ -86,7 +88,7 @@ struct in_tnr_buf {
|
||||
|
||||
struct in_nr_buf {
|
||||
struct rkispp_dummy_buffer tmp_yuv;
|
||||
struct rkispp_dummy_buffer wr[RKISPP_BUF_MAX];
|
||||
struct rkispp_dummy_buffer wr[RKISPP_FEC_BUF_MAX];
|
||||
};
|
||||
|
||||
struct tnr_module {
|
||||
@@ -228,7 +230,6 @@ struct rkispp_vir_cpy {
|
||||
/* rkispp stream device */
|
||||
struct rkispp_stream_vdev {
|
||||
struct rkispp_stream stream[STREAM_MAX];
|
||||
struct rkispp_isp_buf_pool pool[RKISPP_BUF_POOL_MAX];
|
||||
struct tnr_module tnr;
|
||||
struct nr_module nr;
|
||||
struct fec_module fec;
|
||||
|
||||
@@ -282,8 +282,8 @@ static int config_tnr(struct rkispp_device *dev)
|
||||
fmt = dev->isp_mode & (FMT_YUV422 | FMT_FBC);
|
||||
}
|
||||
|
||||
width = dev->ispp_sdev.out_fmt.width;
|
||||
height = dev->ispp_sdev.out_fmt.height;
|
||||
width = dev->ispp_sdev.in_fmt.width;
|
||||
height = dev->ispp_sdev.in_fmt.height;
|
||||
max_w = hw->max_in.w ? hw->max_in.w : width;
|
||||
max_h = hw->max_in.h ? hw->max_in.h : height;
|
||||
w = (fmt & FMT_FBC) ? ALIGN(max_w, 16) : max_w;
|
||||
@@ -416,10 +416,18 @@ static int nr_init_buf(struct rkispp_device *dev, u32 size)
|
||||
{
|
||||
struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
|
||||
struct rkispp_dummy_buffer *buf;
|
||||
int i, ret, cnt = 0;
|
||||
int i, ret, cnt;
|
||||
|
||||
if (vdev->module_ens & ISPP_MODULE_FEC)
|
||||
cnt = vdev->is_done_early ? 1 : RKISPP_BUF_MAX;
|
||||
switch (vdev->module_ens & ISPP_MODULE_FEC_ST) {
|
||||
case ISPP_MODULE_FEC_ST:
|
||||
cnt = RKISPP_FEC_BUF_MAX;
|
||||
break;
|
||||
case ISPP_MODULE_FEC:
|
||||
cnt = RKISPP_BUF_MAX;
|
||||
break;
|
||||
default:
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
buf = &vdev->nr.buf.wr[i];
|
||||
@@ -431,7 +439,7 @@ static int nr_init_buf(struct rkispp_device *dev, u32 size)
|
||||
}
|
||||
|
||||
buf = &vdev->nr.buf.tmp_yuv;
|
||||
cnt = DIV_ROUND_UP(dev->ispp_sdev.out_fmt.width, 32);
|
||||
cnt = DIV_ROUND_UP(dev->ispp_sdev.in_fmt.width, 32);
|
||||
buf->size = PAGE_ALIGN(cnt * 42 * 32);
|
||||
ret = rkispp_allow_buffer(dev, buf);
|
||||
if (ret)
|
||||
@@ -468,8 +476,8 @@ static int config_nr_shp(struct rkispp_device *dev)
|
||||
fmt = dev->isp_mode & (FMT_YUV422 | FMT_FBC);
|
||||
}
|
||||
|
||||
width = dev->ispp_sdev.out_fmt.width;
|
||||
height = dev->ispp_sdev.out_fmt.height;
|
||||
width = dev->ispp_sdev.in_fmt.width;
|
||||
height = dev->ispp_sdev.in_fmt.height;
|
||||
w = width;
|
||||
h = height;
|
||||
max_w = hw->max_in.w ? hw->max_in.w : w;
|
||||
@@ -598,7 +606,8 @@ static int config_fec(struct rkispp_device *dev)
|
||||
{
|
||||
struct rkispp_stream_vdev *vdev;
|
||||
struct rkispp_stream *stream = NULL;
|
||||
u32 width, height, fmt, mult = 1;
|
||||
u32 in_width, in_height, fmt, mult = 1;
|
||||
u32 out_width, out_height;
|
||||
|
||||
vdev = &dev->stream_vdev;
|
||||
vdev->fec.is_end = true;
|
||||
@@ -612,8 +621,10 @@ static int config_fec(struct rkispp_device *dev)
|
||||
fmt = dev->isp_mode & FMT_YUV422;
|
||||
}
|
||||
|
||||
width = dev->ispp_sdev.out_fmt.width;
|
||||
height = dev->ispp_sdev.out_fmt.height;
|
||||
in_width = dev->ispp_sdev.in_fmt.width;
|
||||
in_height = dev->ispp_sdev.in_fmt.height;
|
||||
out_width = dev->ispp_sdev.out_fmt.width;
|
||||
out_height = dev->ispp_sdev.out_fmt.height;
|
||||
|
||||
if (vdev->module_ens & (ISPP_MODULE_NR | ISPP_MODULE_SHP)) {
|
||||
rkispp_write(dev, RKISPP_FEC_RD_Y_BASE,
|
||||
@@ -631,8 +642,8 @@ static int config_fec(struct rkispp_device *dev)
|
||||
if (fmt & FMT_YUYV)
|
||||
mult = 2;
|
||||
rkispp_set_bits(dev, RKISPP_FEC_CTRL, FMT_RD_MASK, fmt);
|
||||
rkispp_write(dev, RKISPP_FEC_RD_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
|
||||
rkispp_write(dev, RKISPP_FEC_DST_SIZE, height << 16 | width);
|
||||
rkispp_write(dev, RKISPP_FEC_RD_VIR_STRIDE, ALIGN(in_width * mult, 16) >> 2);
|
||||
rkispp_write(dev, RKISPP_FEC_PIC_SIZE, out_height << 16 | out_width);
|
||||
rkispp_set_bits(dev, RKISPP_CTRL_QUICK, 0, GLB_FEC2SCL_EN);
|
||||
|
||||
if (vdev->monitor.is_en) {
|
||||
@@ -640,8 +651,8 @@ static int config_fec(struct rkispp_device *dev)
|
||||
schedule_work(&vdev->monitor.fec.work);
|
||||
}
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s size:%dx%d ctrl:0x%x core_ctrl:0x%x\n",
|
||||
__func__, width, height,
|
||||
"%s size:%dx%d->%dx%d ctrl:0x%x core_ctrl:0x%x\n",
|
||||
__func__, in_width, in_height, out_width, out_height,
|
||||
rkispp_read(dev, RKISPP_FEC_CTRL),
|
||||
rkispp_read(dev, RKISPP_FEC_CORE_CTRL));
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user