mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user