media: rockchip: vicap: fixes error of quick stream for AOV without rtt mcu

Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: I502604dba7bb8c3c19e28f3b3e889ff3a72db071
This commit is contained in:
Zefa Chen
2023-11-28 12:43:27 +08:00
committed by 陈泽发
parent 089ceee21e
commit e9ceb67d33
4 changed files with 112 additions and 31 deletions
+97 -29
View File
@@ -676,7 +676,7 @@ static int rkcif_output_fmt_check(struct rkcif_stream *stream,
break;
}
if (ret)
v4l2_err(&stream->cifdev->v4l2_dev,
v4l2_dbg(4, rkcif_debug, &stream->cifdev->v4l2_dev,
"input mbus_code 0x%x, can't transform to %c%c%c%c\n",
input_fmt->mbus_code,
output_fmt->fourcc & 0xff,
@@ -6717,6 +6717,8 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id)
stream->is_single_cap = false;
atomic_set(&stream->buf_cnt, 0);
stream->rx_buf_num = 0;
init_completion(&stream->stop_complete);
stream->is_wait_stop_complete = false;
}
static int rkcif_fh_open(struct file *filp)
@@ -7316,10 +7318,12 @@ static long rkcif_ioctl_default(struct file *file, void *fh,
struct csi_channel_info csi_info;
struct rkcif_fps fps;
int reset_src;
int on = 0;
struct rkcif_quick_stream_param *stream_param;
bool is_single_dev = false;
struct v4l2_subdev *sd;
int ret = -EINVAL;
int i = 0;
int stream_num = 0;
switch (cmd) {
case RKCIF_CMD_GET_CSI_MEMORY_MODE:
@@ -7369,12 +7373,22 @@ static long rkcif_ioctl_default(struct file *file, void *fh,
reset_src = *(int *)arg;
return rkcif_do_reset_work(dev, reset_src);
case RKCIF_CMD_SET_QUICK_STREAM:
on = *(int *)arg;
stream_param = (struct rkcif_quick_stream_param *)arg;
if (!dev->sditf[0])
return -EINVAL;
if (on) {
if (dev->hdr.hdr_mode == HDR_X2)
stream_num = 2;
else if (dev->hdr.hdr_mode == HDR_X3)
stream_num = 3;
else
stream_num = 1;
if (stream_param->on) {
is_single_dev = rkcif_check_single_dev_stream_on(dev->hw_dev);
if (is_single_dev) {
for (i = 0; i < stream_num - 1; i++) {
dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_ISP;
rkcif_enable_dma_capture(&dev->stream[i], true);
}
dev->sditf[0]->mode.rdbk_mode = RKISP_VICAP_ONLINE;
sditf_change_to_online(dev->sditf[0]);
sd = get_rkisp_sd(dev->sditf[0]);
@@ -7386,23 +7400,47 @@ static long rkcif_ioctl_default(struct file *file, void *fh,
return -EINVAL;
}
} else {
dev->sditf[0]->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
sditf_disable_immediately(dev->sditf[0]);
stream->to_en_dma = RKCIF_DMAEN_BY_ISP;
rkcif_enable_dma_capture(stream, true);
for (i = 0; i < stream_num; i++) {
if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_ISP;
else
dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_VICAP;
rkcif_enable_dma_capture(&dev->stream[i], true);
}
}
rkcif_dphy_quick_stream(dev, on);
rkcif_dphy_quick_stream(dev, stream_param->on);
v4l2_subdev_call(dev->terminal_sensor.sd, core, ioctl,
RKMODULE_SET_QUICK_STREAM, &on);
RKMODULE_SET_QUICK_STREAM, &stream_param->on);
} else {
if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
stream->to_stop_dma = RKCIF_DMAEN_BY_ISP;
} else if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ) {
stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP;
} else {
stream->cifdev->sensor_state = 0;
if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
for (i = 0; i < stream_num - 1; i++) {
reinit_completion(&dev->stream[i].stop_complete);
dev->stream[i].is_wait_stop_complete = true;
dev->stream[i].to_stop_dma = RKCIF_DMAEN_BY_ISP;
wait_for_completion_timeout(&dev->stream[i].stop_complete,
msecs_to_jiffies(RKCIF_STOP_MAX_WAIT_TIME_MS));
}
stream->cifdev->sensor_state = stream_param->on;
stream->cifdev->sensor_state_change = true;
dev->stream[i].is_wait_stop_complete = true;
wait_for_completion_timeout(&dev->stream[i].stop_complete,
msecs_to_jiffies(RKCIF_STOP_MAX_WAIT_TIME_MS));
} else {
for (i = 0; i < stream_num; i++) {
dev->stream[i].is_wait_stop_complete = true;
reinit_completion(&dev->stream[i].stop_complete);
if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
dev->stream[i].to_stop_dma = RKCIF_DMAEN_BY_ISP;
else
dev->stream[i].to_stop_dma = RKCIF_DMAEN_BY_VICAP;
wait_for_completion_timeout(&dev->stream[i].stop_complete,
msecs_to_jiffies(RKCIF_STOP_MAX_WAIT_TIME_MS));
}
}
stream_param->frame_num = dev->stream[0].frame_idx - 1;
if (!dev->is_rtt_suspend)
dev->resume_mode = stream_param->resume_mode;
}
break;
default:
@@ -10124,6 +10162,10 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv,
stream->cifdev->sensor_work.on = stream->cifdev->sensor_state;
schedule_work(&stream->cifdev->sensor_work.work);
stream->cifdev->sensor_state_change = false;
if (stream->is_wait_stop_complete) {
stream->is_wait_stop_complete = false;
complete(&stream->stop_complete);
}
}
if (stream->is_single_cap) {
rkcif_dphy_quick_stream(stream->cifdev, on);
@@ -10444,7 +10486,6 @@ static void rkcif_get_resmem_head(struct rkcif_device *cif_dev)
int cam_idx = 0;
char cam_idx_str[3] = {0};
cif_dev->resume_mode = RKISP_RTT_MODE_NORMAL;
if (!cif_dev->is_thunderboot && !cif_dev->is_rtt_suspend)
return;
strscpy(cam_idx_str, cif_dev->terminal_sensor.sd->name + 1, 2);
@@ -10518,7 +10559,7 @@ static int rkcif_subdevs_set_stream(struct rkcif_device *cif_dev, int on)
for (i = 0; i < p->num_subdevs; i++) {
if (p->subdevs[i] == terminal_sensor->sd && on)
rkcif_set_sof(cif_dev, cif_dev->stream[0].frame_idx);
if (p->subdevs[i] == terminal_sensor->sd && cif_dev->is_rtt_suspend) {
if (p->subdevs[i] == terminal_sensor->sd) {
if (!rk_tb_mcu_is_done() && on) {
cif_dev->tb_client.data = p->subdevs[i];
cif_dev->tb_client.cb = rkcif_sensor_quick_streaming_cb;
@@ -10632,6 +10673,7 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
{
struct rkcif_stream *stream = NULL;
struct sditf_priv *priv = cif_dev->sditf[0];
struct v4l2_subdev *sd = NULL;
int ret = 0;
int i = 0;
u32 capture_mode = 0;
@@ -10643,7 +10685,6 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
mutex_lock(&cif_dev->stream_lock);
rkcif_get_resmem_head(cif_dev);
cif_dev->resume_mode = RKISP_RTT_MODE_ONE_FRAME;
is_single_dev = rkcif_check_single_dev_stream_on(cif_dev->hw_dev);
if (cif_dev->resume_mode == RKISP_RTT_MODE_ONE_FRAME) {
if (cif_dev->is_rtt_suspend) {
@@ -10651,12 +10692,20 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
if (priv)
priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
} else {
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
capture_mode = RKCIF_STREAM_MODE_TOISP;
else if (priv && priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
if (cif_dev->chip_id == CHIP_RV1106_CIF) {
capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
} else {
capture_mode = RKCIF_STREAM_MODE_TOISP;
}
} else if (priv &&
(priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME)) {
capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
else
} else {
capture_mode = RKCIF_STREAM_MODE_CAPTURE;
}
}
} else if (cif_dev->resume_mode == RKISP_RTT_MODE_MULTI_FRAME) {
if (is_single_dev) {
@@ -10671,7 +10720,9 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
} else {
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
capture_mode = RKCIF_STREAM_MODE_TOISP;
else if (priv && priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
else if (priv &&
(priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME))
capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
else
capture_mode = RKCIF_STREAM_MODE_CAPTURE;
@@ -10746,6 +10797,18 @@ int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
(priv->hdr_cfg.hdr_mode == HDR_X3 && (stream->id == 0 || stream->id == 1))))
rkcif_init_rx_buf(stream, 1);
} else {
if (stream->is_single_cap && stream->id == 0) {
priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO_ONE_FRAME;
sd = get_rkisp_sd(priv);
if (sd) {
ret = v4l2_subdev_call(sd, core, ioctl,
RKISP_VICAP_CMD_MODE, &priv->mode);
if (ret)
v4l2_err(&cif_dev->v4l2_dev,
"set isp work mode rdbk aotu oneframe fail\n");
}
}
sditf_disable_immediately(priv);
if (!stream->rx_buf_num &&
capture_mode == RKCIF_STREAM_MODE_TOISP_RDBK) {
@@ -11009,6 +11072,13 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
stream->is_finish_stop_dma = false;
continue;
}
if (stream->is_finish_stop_dma && stream->is_wait_stop_complete) {
stream->is_finish_stop_dma = false;
stream->is_wait_stop_complete = false;
complete(&stream->stop_complete);
}
if (stream->crop_dyn_en)
rkcif_dynamic_crop(stream);
@@ -11047,15 +11117,13 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
}
spin_lock_irqsave(&stream->vbq_lock, flags);
if (stream->lack_buf_cnt == 2) {
if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) &&
stream->lack_buf_cnt == 2) {
stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP;
rkcif_stop_dma_capture(stream);
v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
"stream[%d] to stop dma, lack_buf_cnt %d\n",
stream->id, stream->lack_buf_cnt);
if (stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP)
stream->to_stop_dma = RKCIF_DMAEN_BY_ISP;
else
stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP;
rkcif_stop_dma_capture(stream);
}
spin_unlock_irqrestore(&stream->vbq_lock, flags);
if (stream->to_en_scale) {
@@ -94,6 +94,11 @@
#define CROP_SRC_SENSOR_MASK (0x1 << 0)
#define CROP_SRC_USR_MASK (0x1 << 1)
/*
* max wait time for stream stop
*/
#define RKCIF_STOP_MAX_WAIT_TIME_MS (500)
enum rkcif_workmode {
RKCIF_WORKMODE_ONEFRAME = 0x00,
RKCIF_WORKMODE_PINGPONG = 0x01,
@@ -541,6 +546,7 @@ struct rkcif_stream {
int last_frame_idx;
int new_fource_idx;
atomic_t buf_cnt;
struct completion stop_complete;
bool stopping;
bool crop_enable;
bool crop_dyn_en;
@@ -559,6 +565,7 @@ struct rkcif_stream {
bool is_stop_capture;
bool is_wait_dma_stop;
bool is_single_cap;
bool is_wait_stop_complete;
};
struct rkcif_lvds_subdev {
@@ -862,7 +862,7 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
return -EINVAL;
rx_buf = to_cif_rx_buf(dbufs);
v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n",
v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n",
(u32)rx_buf->dummy.dma_addr);
spin_lock_irqsave(&stream->vbq_lock, flags);
stream->last_rx_buf_idx = dbufs->sequence + 1;
+7 -1
View File
@@ -37,7 +37,7 @@
_IOW('V', BASE_VIDIOC_PRIVATE + 7, struct rkcif_csi_info)
#define RKCIF_CMD_SET_QUICK_STREAM \
_IOW('V', BASE_VIDIOC_PRIVATE + 8, int)
_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct rkcif_quick_stream_param)
/* cif memory mode
* 0: raw12/raw10/raw8 8bit memory compact
@@ -82,4 +82,10 @@ struct rkcif_csi_info {
int dphy_vendor[RKCIF_MAX_CSI_NUM];
};
struct rkcif_quick_stream_param {
int on;
__u32 frame_num;
int resume_mode;
};
#endif