media: rockchip: isp: wrap mode for dvbm

Change-Id: I8d20364c03c057465c390107e33ced3e5eb4dcbf
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2022-02-08 14:17:40 +08:00
committed by Tao Huang
parent 5d269355f0
commit bee058dcef
7 changed files with 171 additions and 3 deletions

View File

@@ -44,4 +44,7 @@ video_rkisp-$(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32) += \
isp_params_v32.o \
isp_stats_v32.o
video_rkisp-$(CONFIG_ROCKCHIP_DVBM) += \
isp_dvbm.o
video_rkisp-$(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) += rkisp_tb_helper.o

View File

@@ -438,8 +438,10 @@ int rkisp_stream_frame_start(struct rkisp_device *dev, u32 isp_mis)
struct rkisp_stream *stream;
int i;
if (isp_mis)
if (isp_mis) {
rkisp_dvbm_event(dev, CIF_ISP_V_START);
rkisp_bridge_update_mi(dev, isp_mis);
}
for (i = 0; i < RKISP_MAX_STREAM; i++) {
if (i == RKISP_STREAM_VIR || i == RKISP_STREAM_LUMA)
@@ -1422,6 +1424,33 @@ static int rkisp_set_mirror_flip(struct rkisp_stream *stream,
return 0;
}
static int rkisp_get_wrap_line(struct rkisp_stream *stream, int *line)
{
struct rkisp_device *dev = stream->ispdev;
if (dev->isp_ver != ISP_V32 && stream->id != RKISP_STREAM_MP)
return -EINVAL;
*line = dev->cap_dev.wrap_line;
return 0;
}
static int rkisp_set_wrap_line(struct rkisp_stream *stream, int *line)
{
struct rkisp_device *dev = stream->ispdev;
if (dev->isp_ver != ISP_V32)
return -EINVAL;
if (dev->hw_dev->dev_link_num > 1 || stream->id != RKISP_STREAM_MP) {
v4l2_err(&dev->v4l2_dev,
"wrap only support for single sensor and mainpath\n");
return -EINVAL;
}
dev->cap_dev.wrap_line = *line;
return 0;
}
static long rkisp_ioctl_default(struct file *file, void *fh,
bool valid_prio, unsigned int cmd, void *arg)
{
@@ -1474,6 +1503,12 @@ static long rkisp_ioctl_default(struct file *file, void *fh,
case RKISP_CMD_SET_MIRROR_FLIP:
ret = rkisp_set_mirror_flip(stream, arg);
break;
case RKISP_CMD_GET_WRAP_LINE:
ret = rkisp_get_wrap_line(stream, arg);
break;
case RKISP_CMD_SET_WRAP_LINE:
ret = rkisp_set_wrap_line(stream, arg);
break;
default:
ret = -EINVAL;
}

View File

@@ -1251,6 +1251,7 @@ static int rkisp_create_dummy_buf(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
struct rkisp_dummy_buffer *buf = &stream->dummy_buf;
int ret;
/* mainpath for warp default */
if (!dev->cap_dev.wrap_line || stream->id != RKISP_STREAM_MP)
@@ -1258,7 +1259,14 @@ static int rkisp_create_dummy_buf(struct rkisp_stream *stream)
buf->size = stream->out_fmt.plane_fmt[0].sizeimage;
buf->is_need_dbuf = true;
return rkisp_alloc_buffer(stream->ispdev, buf);
ret = rkisp_alloc_buffer(stream->ispdev, buf);
if (ret == 0) {
ret = rkisp_dvbm_init(stream);
if (ret < 0)
rkisp_free_buffer(dev, buf);
}
return ret;
}
static void rkisp_destroy_dummy_buf(struct rkisp_stream *stream)
@@ -1267,7 +1275,8 @@ static void rkisp_destroy_dummy_buf(struct rkisp_stream *stream)
if (!dev->cap_dev.wrap_line || stream->id != RKISP_STREAM_MP)
return;
rkisp_free_buffer(stream->ispdev, &stream->dummy_buf);
rkisp_dvbm_deinit();
rkisp_free_buffer(dev, &stream->dummy_buf);
}
static void destroy_buf_queue(struct rkisp_stream *stream,
@@ -1604,6 +1613,8 @@ int rkisp_register_stream_v32(struct rkisp_device *dev)
struct rkisp_capture_device *cap_dev = &dev->cap_dev;
int ret;
rkisp_dvbm_get(dev);
ret = rkisp_stream_init(dev, RKISP_STREAM_MP);
if (ret < 0)
goto err;
@@ -1674,6 +1685,9 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev)
mi_frame_end_int_clear(stream);
if (i == RKISP_STREAM_MP)
rkisp_dvbm_event(dev, CIF_MI_MP_FRAME);
if (stream->stopping) {
/*
* Make sure stream is actually stopped, whose state

View File

@@ -32,4 +32,16 @@ static inline void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) {}
static inline void rkisp_mipi_v32_isr(u32 phy, u32 packet, u32 overflow, u32 state, struct rkisp_device *dev) {}
#endif
#if IS_ENABLED(CONFIG_ROCKCHIP_DVBM)
int rkisp_dvbm_get(struct rkisp_device *dev);
int rkisp_dvbm_init(struct rkisp_stream *stream);
void rkisp_dvbm_deinit(void);
int rkisp_dvbm_event(struct rkisp_device *dev, u32 event);
#else
static inline int rkisp_dvbm_get(struct rkisp_device *dev) { return -EINVAL; }
static inline int rkisp_dvbm_init(struct rkisp_stream *stream) { return -EINVAL; }
static inline void rkisp_dvbm_deinit(void) {}
static inline int rkisp_dvbm_event(struct rkisp_device *dev, u32 event) { return -EINVAL; }
#endif
#endif

View File

@@ -79,6 +79,10 @@ static unsigned int rkisp_wait_line;
module_param_named(wait_line, rkisp_wait_line, uint, 0644);
MODULE_PARM_DESC(wait_line, "rkisp wait line to buf done early");
static unsigned int rkisp_wrap_line;
module_param_named(wrap_line, rkisp_wrap_line, uint, 0644);
MODULE_PARM_DESC(wrap_line, "rkisp wrap line for mpp");
static DEFINE_MUTEX(rkisp_dev_mutex);
static LIST_HEAD(rkisp_device_list);
@@ -912,6 +916,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
int ret;
isp_dev->cap_dev.wait_line = rkisp_wait_line;
isp_dev->cap_dev.wrap_line = rkisp_wrap_line;
mutex_lock(&isp_dev->hw_dev->dev_lock);
ret = pm_runtime_get_sync(isp_dev->hw_dev->dev);
mutex_unlock(&isp_dev->hw_dev->dev_lock);

View File

@@ -0,0 +1,93 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Rockchip Electronics Co., Ltd */
#include <linux/of.h>
#include <linux/of_platform.h>
#include <soc/rockchip/rockchip_dvbm.h>
#include "dev.h"
#include "regs.h"
static struct dvbm_port *g_dvbm;
int rkisp_dvbm_get(struct rkisp_device *dev)
{
struct device_node *np = dev->dev->of_node;
struct device_node *np_dvbm = of_parse_phandle(np, "dvbm", 0);
int ret = -EINVAL;
g_dvbm = NULL;
if (dev->isp_ver != ISP_V32)
goto end;
if (!np_dvbm || !of_device_is_available(np_dvbm)) {
dev_warn(dev->dev, "failed to get dvbm node\n");
} else {
struct platform_device *p_dvbm = of_find_device_by_node(np_dvbm);
g_dvbm = rk_dvbm_get_port(p_dvbm, DVBM_ISP_PORT);
of_node_put(np_dvbm);
}
end:
return ret;
}
int rkisp_dvbm_init(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
struct rkisp_dummy_buffer *buf = &stream->dummy_buf;
struct dvbm_isp_cfg_t dvbm_cfg;
u32 width, height, wrap_line;
if (!g_dvbm)
return -EINVAL;
width = stream->out_fmt.plane_fmt[0].bytesperline;
height = stream->out_fmt.height;
wrap_line = dev->cap_dev.wrap_line;
dvbm_cfg.dma_addr = buf->dma_addr;
dvbm_cfg.ybuf_bot = 0;
dvbm_cfg.ybuf_top = width * wrap_line;
dvbm_cfg.ybuf_lstd = width;
dvbm_cfg.ybuf_fstd = width * height;
dvbm_cfg.cbuf_bot = dvbm_cfg.ybuf_top;
dvbm_cfg.cbuf_top = dvbm_cfg.cbuf_bot + (width * wrap_line / 2);
dvbm_cfg.cbuf_lstd = width;
dvbm_cfg.cbuf_fstd = dvbm_cfg.ybuf_fstd / 2;
rk_dvbm_ctrl(g_dvbm, DVBM_ISP_SET_CFG, &dvbm_cfg);
rk_dvbm_link(g_dvbm);
return 0;
}
void rkisp_dvbm_deinit(void)
{
if (g_dvbm)
rk_dvbm_unlink(g_dvbm);
}
int rkisp_dvbm_event(struct rkisp_device *dev, u32 event)
{
enum dvbm_cmd cmd;
u32 seq;
if (!g_dvbm || dev->isp_ver != ISP_V32 ||
!dev->cap_dev.wrap_line)
return -EINVAL;
rkisp_dmarx_get_frame(dev, &seq, NULL, NULL, true);
switch (event) {
case CIF_ISP_V_START:
cmd = DVBM_ISP_FRM_START;
break;
case CIF_MI_MP_FRAME:
cmd = DVBM_ISP_FRM_END;
break;
default:
return -EINVAL;
}
return rk_dvbm_ctrl(g_dvbm, cmd, &seq);
}

View File

@@ -67,6 +67,12 @@
#define RKISP_CMD_SET_MIRROR_FLIP \
_IOW('V', BASE_VIDIOC_PRIVATE + 106, struct rkisp_mirror_flip)
#define RKISP_CMD_GET_WRAP_LINE \
_IOR('V', BASE_VIDIOC_PRIVATE + 107, int)
/* set wrap line before VIDIOC_S_FMT */
#define RKISP_CMD_SET_WRAP_LINE \
_IOW('V', BASE_VIDIOC_PRIVATE + 108, int)
/*************************************************************/
#define ISP2X_ID_DPCC (0)