media: rockchip: vpss: fix wrap for vpss online

Change-Id: I98aa2329b228f889ee08fbdf3239546087b928e0
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2025-04-01 11:32:13 +08:00
committed by Tao Huang
parent 90b3d70d79
commit 30478a0151
4 changed files with 51 additions and 30 deletions

View File

@@ -263,7 +263,7 @@
/* VPSS2ENC_DEBUG */
#define RKVPSS2X_RO_VPSS2ENC_LINE_CNT(x) ((x) & 0x3fff)
#define RKVPSS2X_RO_VPSS2ENC_FRM_CNT(x) (((x) & 0xffffff) >> 16)
#define RKVPSS2X_RO_VPSS2ENC_FRM_CNT(x) (((x) >> 16) & 0xff)
/* VPSS_CTRL_SHD */

View File

@@ -826,7 +826,10 @@ static void stream_frame_start(struct rkvpss_stream *stream, u32 irq)
!stream->dev->hw_dev->is_single)
stream->ops->update_mi(stream);
if (dev->stream_vdev.wrap_line) {
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) {
/* vpss can be holded by enc if isp input offline */
if (!irq)
rkvpss_unite_set_bits(dev, RKVPSS_VPSS_CTRL, 0, RKVPSS_VPSS2ENC_PIPE_EN);
rkvpss_rockit_frame_start(dev);
rkvpss_dvbm_event(dev, ROCKIT_DVBM_START);
}
@@ -898,8 +901,8 @@ static void scl_update_mi(struct rkvpss_stream *stream)
stream->ops->enable_mi(stream);
}
} else if (!stream->is_pause) {
/* wrap mode don't disable mi */
if (stream->id != RKVPSS_OUTPUT_CH0 || !dev->stream_vdev.wrap_line) {
/* wrap mode don't disable mi for ch0 */
if (!dev->stream_vdev.wrap_line || stream->id != RKVPSS_OUTPUT_CH0) {
stream->is_pause = true;
stream->ops->disable_mi(stream);
}
@@ -918,15 +921,11 @@ static void scl_config_mi(struct rkvpss_stream *stream)
struct rkvpss_device *dev = stream->dev;
struct capture_fmt *fmt = &stream->out_cap_fmt;
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
u32 reg, val, mask;
v4l2_dbg(4, rkvpss_debug, &dev->v4l2_dev,
"%s stream:%d\n", __func__, stream->id);
u32 reg, val, mask, height = out_fmt->height;
val = out_fmt->plane_fmt[0].bytesperline;
reg = stream->config->mi.stride;
rkvpss_unite_write(dev, reg, val);
rkvpss_unite_write(dev, reg, val);
switch (fmt->fourcc) {
case V4L2_PIX_FMT_RGB565:
@@ -942,18 +941,27 @@ static void scl_config_mi(struct rkvpss_stream *stream)
break;
}
val = val * out_fmt->height;
val = val * height;
reg = stream->config->mi.y_pic_size;
rkvpss_unite_write(dev, reg, val);
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
val = out_fmt->plane_fmt[0].bytesperline * dev->stream_vdev.wrap_line;
else
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) {
mask = RKVPSS_VPSS2ENC_SEL | RKVPSS2X_SENSOR_ID(7) |
RKVPSS_VPSS2ENC_CNT_SEL;
val = RKVPSS_VPSS2ENC_SEL | RKVPSS2X_VPSS2ENC_PATH_EN |
RKVPSS2X_SENSOR_ID(dev->dev_id);
rkvpss_unite_set_bits(dev, RKVPSS_VPSS_CTRL, mask, val);
height = dev->stream_vdev.wrap_line;
}
val = out_fmt->plane_fmt[0].bytesperline * height;
reg = stream->config->mi.y_size;
rkvpss_unite_write(dev, reg, val);
val = out_fmt->plane_fmt[1].sizeimage;
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
val = out_fmt->plane_fmt[0].bytesperline * height / 2;
else
val = out_fmt->plane_fmt[1].sizeimage;
reg = stream->config->mi.uv_size;
rkvpss_unite_write(dev, reg, val);
@@ -1154,14 +1162,14 @@ static void rkvpss_frame_end(struct rkvpss_stream *stream)
struct rkvpss_buffer *buf = NULL;
unsigned long lock_flags = 0;
v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev,
"%s stream:%d\n", __func__, stream->id);
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
if (stream->curr_buf) {
buf = stream->curr_buf;
/* wrap mode use one buffer */
if (stream->curr_buf->vb.vb2_buf.memory || !dev->stream_vdev.wrap_line)
/* rockit wrap mode use one buffer for ch0 */
if (stream->curr_buf->vb.vb2_buf.memory ||
!dev->stream_vdev.wrap_line || stream->id != RKVPSS_OUTPUT_CH0) {
buf = stream->curr_buf;
stream->curr_buf = NULL;
}
}
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
@@ -1270,6 +1278,8 @@ static void rkvpss_buf_queue(struct vb2_buffer *vb)
if (cap_fmt->mplanes == 1) {
for (i = 0; i < cap_fmt->cplanes - 1; i++) {
height = pixm->height;
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
height = dev->stream_vdev.wrap_line;
size = (i == 0) ?
pixm->plane_fmt[i].bytesperline * height :
pixm->plane_fmt[i].sizeimage;
@@ -1910,6 +1920,8 @@ static void rkvpss_stop_streaming(struct vb2_queue *queue)
rkvpss_stream_stop(stream);
rkvpss_pipeline_stream(dev, false);
}
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
rkvpss_dvbm_deinit(dev);
destroy_buf_queue(stream, VB2_BUF_STATE_ERROR);
rkvpss_pipeline_close(dev);
tasklet_disable(&stream->buf_done_tasklet);
@@ -2022,7 +2034,8 @@ static int rkvpss_start_streaming(struct vb2_queue *queue, unsigned int count)
v4l2_err(&dev->v4l2_dev, "start %s failed\n", node->vdev.name);
goto pipe_close;
}
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
rkvpss_dvbm_init(stream);
ret = rkvpss_pipeline_stream(dev, true);
if (ret < 0)
goto stop_stream;
@@ -2037,6 +2050,8 @@ static int rkvpss_start_streaming(struct vb2_queue *queue, unsigned int count)
mutex_unlock(&hw->dev_lock);
return 0;
stop_stream:
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
rkvpss_dvbm_deinit(dev);
stream->streaming = false;
rkvpss_stream_stop(stream);
pipe_close:
@@ -2758,9 +2773,6 @@ static int rkvpss_set_wrap_line(struct rkvpss_stream *stream, int *wrap_line)
return -EINVAL;
vpss_dev->stream_vdev.wrap_line = *wrap_line;
//set_wrap todo
return 0;
}

View File

@@ -20,7 +20,7 @@ static struct dvbm_port *g_dvbm;
int rkvpss_dvbm_get(struct rkvpss_device *vpss_dev)
{
struct device_node *np = vpss_dev->dev->of_node;
struct device_node *np = vpss_dev->hw_dev->dev->of_node;
struct device_node *np_dvbm = of_parse_phandle(np, "dvbm", 0);
int ret = 0;
@@ -35,7 +35,10 @@ int rkvpss_dvbm_get(struct rkvpss_device *vpss_dev)
}
of_node_put(np_dvbm);
if (IS_ERR_OR_NULL(g_dvbm)) {
g_dvbm = NULL;
ret = -EINVAL;
}
return ret;
}
@@ -63,7 +66,7 @@ int rkvpss_dvbm_init(struct rkvpss_stream *stream)
dvbm_cfg.cbuf_fstd = dvbm_cfg.ybuf_fstd / 2;
rk_dvbm_ctrl(g_dvbm, DVBM_VPSS_SET_CFG, &dvbm_cfg);
rk_dvbm_link(g_dvbm, 0);
rk_dvbm_link(g_dvbm, vpss_dev->dev_id);
return 0;
}
@@ -73,7 +76,7 @@ void rkvpss_dvbm_deinit(struct rkvpss_device *vpss_dev)
pr_err("g_dvbm %p or vpss_dev %p is NULL\n", g_dvbm, vpss_dev);
return;
}
rk_dvbm_unlink(g_dvbm, 0);
rk_dvbm_unlink(g_dvbm, vpss_dev->dev_id);
}
int rkvpss_dvbm_event(struct rkvpss_device *vpss_dev, u32 event)

View File

@@ -292,12 +292,17 @@ int rkvpss_rockit_buf_done(struct rkvpss_stream *stream, int cmd, struct rkvpss_
curr_buf->vb.sequence,
curr_buf->dma[0]);
} else {
//tosee
if (!(stream->dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0))
return 0;
rockit_vpss_cfg->frame.u64PTS = vpss_dev->vpss_sdev.frame_timestamp;
rockit_vpss_cfg->frame.u32TimeRef = vpss_dev->vpss_sdev.frame_seq;
rockit_vpss_cfg->frame.ispEncCnt =
RKVPSS2X_RO_VPSS2ENC_FRM_CNT(rkvpss_hw_read(vpss_dev->hw_dev, RKVPSS2X_VPSS2ENC_DEBUG));
v4l2_dbg(2, rkvpss_debug, &vpss_dev->v4l2_dev,
"stream:%d seq:%d enc_frm_cnt:%d rockit buf done:0x%x\n",
stream->id, curr_buf->vb.sequence,
rockit_vpss_cfg->frame.ispEncCnt, curr_buf->dma[0]);
}
rockit_vpss_cfg->frame.u32Height = stream->out_fmt.height;
@@ -571,7 +576,8 @@ void rkvpss_rockit_frame_start(struct rkvpss_device *dev)
stream = &dev->stream_vdev.stream[i];
if (!stream->streaming)
continue;
rkvpss_rockit_buf_done(stream, ROCKIT_DVBM_START, stream->curr_buf);
if (stream->curr_buf && !stream->curr_buf->vb.vb2_buf.memory)
rkvpss_rockit_buf_done(stream, ROCKIT_DVBM_START, stream->curr_buf);
}
}