media: rockchip: ispp: tnr support dynamic switch

Change-Id: Id22d59b17b853729622cd2f0a13fcd272d7c371d
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2020-09-04 18:14:19 +08:00
committed by Tao Huang
parent caf551f781
commit 533d819cf4
4 changed files with 64 additions and 39 deletions

View File

@@ -7,8 +7,8 @@
#include <linux/platform_device.h>
#include <media/v4l2-subdev.h>
#define RKISPP_BUF_MAX 3
#define RKISP_ISPP_BUF_MAX (RKISPP_BUF_MAX + (2 * DEV_MAX))
#define RKISPP_BUF_MAX 5
#define RKISP_ISPP_BUF_MAX (RKISPP_BUF_MAX + (2 * (DEV_MAX - 1)))
#define RKISP_ISPP_CMD_SET_MODE \
_IOW('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_ispp_mode)
@@ -66,6 +66,7 @@ struct rkisp_ispp_buf {
u64 frame_timestamp;
u32 frame_id;
u32 index;
bool is_isp;
};
#if IS_BUILTIN(CONFIG_VIDEO_ROCKCHIP_ISP) && IS_BUILTIN(CONFIG_VIDEO_ROCKCHIP_ISPP)

View File

@@ -189,6 +189,7 @@ static int rkispp_init_pool(struct rkispp_hw_dev *hw, struct rkisp_ispp_buf *dbu
if (!pool->dbufs)
break;
}
dbufs->is_isp = true;
pool->dbufs = dbufs;
if (rkispp_debug)
dev_info(hw->dev, "%s dbufs[%d]:0x%p\n",

View File

@@ -171,11 +171,6 @@ static void tnr_config(struct rkispp_params_vdev *params_vdev,
rkispp_write(params_vdev->dev, RKISPP_TNR_CORE_WEIGHT, val);
}
static void tnr_enable(struct rkispp_params_vdev *params_vdev, bool en)
{
rkispp_set_bits(params_vdev->dev, RKISPP_TNR_CORE_CTRL, SW_TNR_EN, en);
}
static bool is_tnr_enable(struct rkispp_params_vdev *params_vdev)
{
u32 cur_en;
@@ -186,6 +181,13 @@ static bool is_tnr_enable(struct rkispp_params_vdev *params_vdev)
return (!!cur_en);
}
static void tnr_enable(struct rkispp_params_vdev *params_vdev, bool en)
{
if (en && !is_tnr_enable(params_vdev))
rkispp_set_bits(params_vdev->dev, RKISPP_TNR_CTRL, 0, SW_TNR_1ST_FRM);
rkispp_set_bits(params_vdev->dev, RKISPP_TNR_CORE_CTRL, SW_TNR_EN, en);
}
static void nr_config(struct rkispp_params_vdev *params_vdev,
struct rkispp_nr_config *arg)
{

View File

@@ -458,6 +458,7 @@ static int tnr_init_buf(struct rkispp_device *dev,
ret = -ENOMEM;
goto err;
}
dbufs->is_isp = false;
for (j = 0; j < GROUP_BUF_MAX; j++) {
buf = &vdev->tnr.buf.wr[i][j];
buf->is_need_dbuf = true;
@@ -576,7 +577,7 @@ static int config_tnr(struct rkispp_device *dev)
rkispp_write(dev, RKISPP_TNR_GAIN_WR_Y_BASE, val);
rkispp_write(dev, RKISPP_TNR_WR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
rkispp_write(dev, RKISPP_TNR_CTRL, fmt << 4 | SW_TNR_1ST_FRM);
rkispp_set_bits(dev, RKISPP_TNR_CTRL, FMT_WR_MASK, fmt << 4 | SW_TNR_1ST_FRM);
}
if (stream) {
@@ -627,7 +628,10 @@ static void nr_free_buf(struct rkispp_device *dev)
}
while (!list_empty(list)) {
dbufs = get_list_buf(list, true);
if (vdev->module_ens & ISPP_MODULE_TNR)
if (dbufs->is_isp)
v4l2_subdev_call(dev->ispp_sdev.remote_sd,
video, s_rx_buffer, dbufs, NULL);
else
kfree(dbufs);
}
@@ -739,9 +743,13 @@ static int config_nr_shp(struct rkispp_device *dev)
/* tnr need to set same format with nr in the fbc mode */
rkispp_set_bits(dev, RKISPP_TNR_CTRL, FMT_RD_MASK, fmt);
if (dev->inp == INP_ISP) {
rkispp_set_bits(dev, RKISPP_CTRL_QUICK,
GLB_QUICK_MODE_MASK,
GLB_QUICK_MODE(2));
if (dev->isp_mode & ISP_ISPP_QUICK)
rkispp_set_bits(dev, RKISPP_CTRL_QUICK,
GLB_QUICK_MODE_MASK,
GLB_QUICK_MODE(2));
else
rkispp_set_bits(dev, RKISPP_NR_UVNR_CTRL_PARA,
0, SW_UVNR_SD32_SELF_EN);
val = vdev->pool[0].dma[GROUP_BUF_PIC];
rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, val);
@@ -1511,12 +1519,11 @@ static int start_isp(struct rkispp_device *dev)
mutex_lock(&dev->hw_dev->dev_lock);
mode.work_mode = dev->isp_mode;
mode.buf_num = (dev->isp_mode & ISP_ISPP_QUICK) ?
1 : RKISPP_BUF_MAX;
i = 1;
if ((vdev->module_ens & ISPP_MODULE_TNR_3TO1) == ISPP_MODULE_TNR_3TO1)
i++;
mode.buf_num += i * dev->hw_dev->dev_num;
mode.buf_num = RKISPP_BUF_MAX;
if (dev->isp_mode & ISP_ISPP_QUICK)
mode.buf_num = ((vdev->module_ens & ISPP_MODULE_TNR_3TO1) ==
ISPP_MODULE_TNR_3TO1) ? 2 : 1;
mode.buf_num += 2 * (dev->hw_dev->dev_num - 1);
ret = v4l2_subdev_call(ispp_sdev->remote_sd, core, ioctl,
RKISP_ISPP_CMD_SET_MODE, &mode);
if (ret)
@@ -2038,7 +2045,7 @@ static void nr_work_event(struct rkispp_device *dev,
struct dma_buf *dbuf;
unsigned long lock_flags = 0;
bool is_start = false, is_quick = false;
bool is_tnr_en = (vdev->module_ens & ISPP_MODULE_TNR);
bool is_tnr_en = vdev->module_ens & ISPP_MODULE_TNR;
bool is_fec_en = (vdev->module_ens & ISPP_MODULE_FEC);
u32 val;
@@ -2048,7 +2055,7 @@ static void nr_work_event(struct rkispp_device *dev,
if (dev->inp == INP_ISP) {
if (dev->isp_mode & ISP_ISPP_QUICK)
is_quick = true;
else if (!is_tnr_en)
else
sd = dev->ispp_sdev.remote_sd;
}
@@ -2060,7 +2067,7 @@ static void nr_work_event(struct rkispp_device *dev,
if (vdev->nr.cur_rd) {
/* nr read buf return to isp or tnr */
if (sd)
if (vdev->nr.cur_rd->is_isp)
v4l2_subdev_call(sd, video, s_rx_buffer,
vdev->nr.cur_rd, NULL);
else
@@ -2112,7 +2119,7 @@ static void nr_work_event(struct rkispp_device *dev,
}
if (vdev->nr.cur_rd && vdev->nr.is_end) {
if (is_tnr_en) {
if (!vdev->nr.cur_rd->is_isp) {
u32 size = sizeof(vdev->tnr.buf) / sizeof(*dummy);
dbuf = vdev->nr.cur_rd->dbuf[GROUP_BUF_PIC];
@@ -2122,12 +2129,10 @@ static void nr_work_event(struct rkispp_device *dev,
val += vdev->nr.uv_offset;
rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV, val);
if (rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN) {
dbuf = vdev->nr.cur_rd->dbuf[GROUP_BUF_GAIN];
dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
val = dummy->dma_addr;
rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN, val);
}
dbuf = vdev->nr.cur_rd->dbuf[GROUP_BUF_GAIN];
dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
val = dummy->dma_addr;
rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN, val);
} else {
struct rkispp_isp_buf_pool *buf;
@@ -2225,6 +2230,7 @@ static void tnr_work_event(struct rkispp_device *dev,
unsigned long lock_flags = 0;
u32 val, size = sizeof(vdev->tnr.buf) / sizeof(*dummy);
bool is_3to1 = vdev->tnr.is_3to1, is_start = false, is_skip = false;
bool is_en = rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN;
if (!(vdev->module_ens & ISPP_MODULE_TNR) ||
(dev->inp == INP_ISP && dev->isp_mode & ISP_ISPP_QUICK))
@@ -2256,6 +2262,28 @@ static void tnr_work_event(struct rkispp_device *dev,
}
}
if (!is_en) {
if (buf_wr)
list_add_tail(&buf_wr->list, &vdev->tnr.list_wr);
if (vdev->tnr.nxt_rd) {
v4l2_subdev_call(sd, video, s_rx_buffer,
vdev->tnr.nxt_rd, NULL);
vdev->tnr.nxt_rd = NULL;
}
list = &vdev->tnr.list_rd;
while (!list_empty(list)) {
struct rkisp_ispp_buf *buf = get_list_buf(list, true);
rkispp_module_work_event(dev, buf, NULL,
ISPP_MODULE_NR, is_isr);
}
if (buf_rd)
rkispp_module_work_event(dev, buf_rd, NULL,
ISPP_MODULE_NR, is_isr);
goto end;
}
list = &vdev->tnr.list_rd;
if (buf_rd && vdev->tnr.is_end && list_empty(list)) {
/* tnr read buf from isp */
@@ -2308,14 +2336,6 @@ static void tnr_work_event(struct rkispp_device *dev,
val = buf->dma[GROUP_BUF_GAIN];
rkispp_write(dev, RKISPP_TNR_GAIN_CUR_Y_BASE, val);
if (rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN) {
rkispp_set_bits(dev, RKISPP_CTRL_QUICK, 0,
GLB_NR_SD32_TNR);
} else {
rkispp_clear_bits(dev, RKISPP_CTRL_QUICK,
GLB_NR_SD32_TNR);
rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN, val);
}
if (is_3to1) {
buf = get_pool_buf(dev, vdev->tnr.nxt_rd);
val = buf->dma[GROUP_BUF_PIC];
@@ -2395,6 +2415,7 @@ static void tnr_work_event(struct rkispp_device *dev,
vdev->tnr.nxt_rd = NULL;
vdev->tnr.cur_rd = NULL;
}
end:
spin_unlock_irqrestore(&vdev->tnr.buf_lock, lock_flags);
}
@@ -2451,13 +2472,13 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev)
(dev->isp_mode & ISP_ISPP_QUICK || dev->inp == INP_DDR))
atomic_inc(&dev->ispp_sdev.frm_sync_seq);
rkispp_params_isr(&dev->params_vdev, mis_val);
rkispp_stats_isr(&dev->stats_vdev, mis_val);
if (mis_val & TNR_INT)
if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM)
rkispp_clear_bits(dev, RKISPP_TNR_CTRL, SW_TNR_1ST_FRM);
rkispp_params_isr(&dev->params_vdev, mis_val);
rkispp_stats_isr(&dev->stats_vdev, mis_val);
for (i = 0; i < STREAM_MAX; i++) {
stream = &vdev->stream[i];