media: rockchip: vicap fixes error when work on both thunderboot and quick suspend/resume

Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: Ied9db7a3ed4e63735066424c48b6870830284588
This commit is contained in:
Zefa Chen
2023-10-31 10:32:40 +08:00
parent 49b335bda8
commit 61949a9b21
3 changed files with 91 additions and 38 deletions

View File

@@ -4560,12 +4560,43 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num)
struct rkcif_rx_buffer *buf;
struct rkcif_device *dev = stream->cifdev;
struct sditf_priv *priv = dev->sditf[0];
struct v4l2_subdev *sd;
int i = 0;
unsigned long flags;
if (!priv)
return;
sd = get_rkisp_sd(dev->sditf[0]);
if (!sd)
return;
if (dev->is_rtt_suspend && dev->is_thunderboot) {
stream->curr_buf_toisp = NULL;
stream->next_buf_toisp = NULL;
INIT_LIST_HEAD(&stream->rx_buf_head);
for (i = 0; i < buf_num; i++) {
buf = &stream->rx_buf[i];
if (buf->dbufs.is_init)
v4l2_subdev_call(sd, core, ioctl,
RKISP_VICAP_CMD_RX_BUFFER_FREE, &buf->dbufs);
buf->dummy.is_free = true;
}
if (buf_num > 2) {
for (i = buf_num - 1; i >= 2; i--) {
buf = &stream->rx_buf[i];
list_add_tail(&buf->list_free, &priv->buf_free_list);
}
schedule_work(&priv->buffree_work.work);
atomic_set(&stream->buf_cnt, 0);
stream->total_buf_num = 0;
stream->rx_buf_num = 0;
}
return;
}
spin_lock_irqsave(&stream->vbq_lock, flags);
stream->curr_buf_toisp = NULL;
stream->next_buf_toisp = NULL;
@@ -4578,6 +4609,9 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num)
buf = &stream->rx_buf[i];
if (buf->dummy.is_free)
continue;
if (buf->dbufs.is_init)
v4l2_subdev_call(sd, core, ioctl,
RKISP_VICAP_CMD_RX_BUFFER_FREE, &buf->dbufs);
if (!dev->is_thunderboot)
rkcif_free_buffer(dev, &buf->dummy);
else
@@ -4585,6 +4619,7 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num)
atomic_dec(&stream->buf_cnt);
stream->total_buf_num--;
}
stream->rx_buf_num = 0;
if (dev->is_thunderboot) {
spin_unlock_irqrestore(&dev->buffree_lock, flags);
@@ -4645,7 +4680,7 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
buf->buf_idx = i;
ret = rkcif_alloc_reserved_mem_buf(dev, buf);
if (ret) {
priv->buf_num = i;
stream->rx_buf_num = i;
v4l2_info(&dev->v4l2_dev,
"reserved mem support alloc buf num %d, require buf num %d\n",
i, buf_num);
@@ -4658,7 +4693,7 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
} else {
ret = rkcif_alloc_buffer(dev, dummy);
if (ret) {
priv->buf_num = i;
stream->rx_buf_num = i;
v4l2_info(&dev->v4l2_dev,
"alloc buf num %d, require buf num %d\n",
i, buf_num);
@@ -4681,10 +4716,10 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
}
i++;
if (!dev->is_thunderboot && i >= buf_num) {
priv->buf_num = buf_num;
stream->rx_buf_num = buf_num;
break;
} else if (i >= RKISP_VICAP_BUF_CNT_MAX) {
priv->buf_num = i;
stream->rx_buf_num = i;
v4l2_info(&dev->v4l2_dev,
"reserved mem alloc buf num %d\n", i);
break;
@@ -4693,9 +4728,9 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
"init rx_buf,dma_addr 0x%llx size: 0x%x\n",
(u64)dummy->dma_addr, pixm->plane_fmt[0].sizeimage);
}
if (priv->buf_num) {
stream->total_buf_num = priv->buf_num;
atomic_set(&stream->buf_cnt, priv->buf_num);
if (stream->rx_buf_num) {
stream->total_buf_num = stream->rx_buf_num;
atomic_set(&stream->buf_cnt, stream->rx_buf_num);
return 0;
} else {
return -EINVAL;
@@ -6632,6 +6667,7 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id)
stream->is_stop_capture = false;
stream->is_single_cap = false;
atomic_set(&stream->buf_cnt, 0);
stream->rx_buf_num = 0;
}
static int rkcif_fh_open(struct file *filp)
@@ -10624,20 +10660,31 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
}
spin_unlock_irqrestore(&stream->vbq_lock, flags);
if (priv) {
if (capture_mode == RKCIF_STREAM_MODE_TOISP)
if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
sditf_change_to_online(priv);
else
if (cif_dev->resume_mode == RKISP_RTT_MODE_MULTI_FRAME &&
stream->rx_buf_num &&
(priv->hdr_cfg.hdr_mode == NO_HDR ||
(priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 1) ||
(priv->hdr_cfg.hdr_mode == HDR_X3 && stream->id == 2)))
rkcif_free_rx_buf(stream, priv->buf_num);
else if (!stream->rx_buf_num &&
((priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 0) ||
(priv->hdr_cfg.hdr_mode == HDR_X3 && (stream->id == 0 || stream->id == 1))))
rkcif_init_rx_buf(stream, 1);
} else {
sditf_disable_immediately(priv);
if (!stream->rx_buf_num &&
capture_mode == RKCIF_STREAM_MODE_TOISP_RDBK) {
if (cif_dev->resume_mode == RKISP_RTT_MODE_ONE_FRAME)
rkcif_init_rx_buf(stream, 1);
else
rkcif_init_rx_buf(stream, priv->buf_num);
}
}
}
if (!stream->total_buf_num && priv &&
(capture_mode == RKCIF_STREAM_MODE_TOISP_RDBK ||
(capture_mode == RKCIF_STREAM_MODE_TOISP &&
((priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 0) ||
(priv->hdr_cfg.hdr_mode == HDR_X3 && (stream->id == 0 || stream->id == 1))))))
rkcif_init_rx_buf(stream, 1);
if (priv && cif_dev->resume_mode == RKISP_RTT_MODE_MULTI_FRAME && stream->total_buf_num)
rkcif_init_rx_buf(stream, priv->buf_num);
stream->lack_buf_cnt = 0;
if (cif_dev->active_sensor &&

View File

@@ -530,6 +530,7 @@ struct rkcif_stream {
struct rkcif_rx_buffer rx_buf[RKISP_VICAP_BUF_CNT_MAX];
struct list_head rx_buf_head;
int total_buf_num;
int rx_buf_num;
u64 line_int_cnt;
int lack_buf_cnt;
unsigned int buf_wake_up_cnt;

View File

@@ -283,14 +283,14 @@ static void sditf_free_buf(struct sditf_priv *priv)
struct rkcif_device *cif_dev = priv->cif_dev;
if (priv->hdr_cfg.hdr_mode == HDR_X2) {
rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
rkcif_free_rx_buf(&cif_dev->stream[2], cif_dev->stream[2].rx_buf_num);
} else {
rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
}
if (cif_dev->is_thunderboot) {
cif_dev->wait_line_cache = 0;
@@ -622,22 +622,26 @@ void sditf_change_to_online(struct sditf_priv *priv)
sditf_channel_enable(priv, 0);
sditf_channel_enable(priv, 1);
}
if (priv->hdr_cfg.hdr_mode == NO_HDR) {
rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
cif_dev->stream[0].is_line_wake_up = false;
} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
cif_dev->stream[0].is_line_wake_up = false;
cif_dev->stream[1].is_line_wake_up = false;
} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
cif_dev->stream[0].is_line_wake_up = false;
cif_dev->stream[1].is_line_wake_up = false;
cif_dev->stream[2].is_line_wake_up = false;
if (cif_dev->is_thunderboot) {
if (priv->hdr_cfg.hdr_mode == NO_HDR) {
rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
cif_dev->stream[0].is_line_wake_up = false;
} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
cif_dev->stream[0].is_line_wake_up = false;
cif_dev->stream[1].is_line_wake_up = false;
} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
rkcif_free_rx_buf(&cif_dev->stream[2], cif_dev->stream[2].rx_buf_num);
cif_dev->stream[0].is_line_wake_up = false;
cif_dev->stream[1].is_line_wake_up = false;
cif_dev->stream[2].is_line_wake_up = false;
}
cif_dev->wait_line_cache = 0;
cif_dev->wait_line = 0;
cif_dev->wait_line_bak = 0;
cif_dev->is_thunderboot = false;
}
cif_dev->wait_line_cache = 0;
cif_dev->wait_line = 0;
cif_dev->wait_line_bak = 0;
}
void sditf_disable_immediately(struct sditf_priv *priv)
@@ -862,6 +866,7 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
if (!list_empty(&stream->rx_buf_head) &&
cif_dev->is_thunderboot &&
(!cif_dev->is_rtt_suspend) &&
(dbufs->type == BUF_SHORT ||
(dbufs->type != BUF_SHORT && (!dbufs->is_switch)))) {
spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);