mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
media: rockchip: isp: wrap mode for dvbm
Change-Id: I8d20364c03c057465c390107e33ced3e5eb4dcbf Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
93
drivers/media/platform/rockchip/isp/isp_dvbm.c
Normal file
93
drivers/media/platform/rockchip/isp/isp_dvbm.c
Normal 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);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user