media: rockchip: vicap fixes suspend/resume
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: I1d7e7d8f521fca3bda4f3599a7b34233e1a94bc2 Signed-off-by: Mingwei Yan <mingwei.yan@rock-chips.com>
This commit is contained in:
@@ -1913,6 +1913,9 @@ static void rkcif_assign_new_buffer_init_toisp(struct rkcif_stream *stream,
|
||||
} else {
|
||||
rkcif_write_register(dev, frm0_addr_y, buff_addr_y);
|
||||
}
|
||||
} else {
|
||||
if (stream->lack_buf_cnt < 2)
|
||||
stream->lack_buf_cnt++;
|
||||
}
|
||||
|
||||
if (!stream->next_buf_toisp) {
|
||||
@@ -1938,6 +1941,9 @@ static void rkcif_assign_new_buffer_init_toisp(struct rkcif_stream *stream,
|
||||
} else {
|
||||
rkcif_write_register(dev, frm1_addr_y, buff_addr_y);
|
||||
}
|
||||
} else {
|
||||
if (stream->lack_buf_cnt < 2)
|
||||
stream->lack_buf_cnt++;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
@@ -1970,10 +1976,7 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
if (!list_empty(&stream->rx_buf_head)) {
|
||||
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
||||
if (stream->curr_buf_toisp == stream->next_buf_toisp)
|
||||
active_buf = NULL;
|
||||
else
|
||||
active_buf = stream->curr_buf_toisp;
|
||||
active_buf = stream->curr_buf_toisp;
|
||||
|
||||
buffer = list_first_entry(&stream->rx_buf_head,
|
||||
struct rkcif_rx_buffer, list);
|
||||
@@ -1999,15 +2002,13 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
rkcif_rdbk_frame_end_toisp(stream, active_buf);
|
||||
}
|
||||
} else {
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
if (active_buf)
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
if (dev->is_support_tools && stream->tools_vdev)
|
||||
rkcif_rdbk_with_tools(stream, active_buf);
|
||||
}
|
||||
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
||||
if (stream->curr_buf_toisp == stream->next_buf_toisp)
|
||||
active_buf = NULL;
|
||||
else
|
||||
active_buf = stream->next_buf_toisp;
|
||||
active_buf = stream->next_buf_toisp;
|
||||
buffer = list_first_entry(&stream->rx_buf_head,
|
||||
struct rkcif_rx_buffer, list);
|
||||
if (buffer) {
|
||||
@@ -2032,7 +2033,8 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
rkcif_rdbk_frame_end_toisp(stream, active_buf);
|
||||
}
|
||||
} else {
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
if (active_buf)
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
if (dev->is_support_tools && stream->tools_vdev)
|
||||
rkcif_rdbk_with_tools(stream, active_buf);
|
||||
}
|
||||
@@ -2068,6 +2070,18 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
"stream[%d] hold buf %x\n",
|
||||
stream->id,
|
||||
(u32)stream->next_buf_toisp->dummy.dma_addr);
|
||||
} else {
|
||||
if (stream->curr_buf_toisp)
|
||||
active_buf = stream->curr_buf_toisp;
|
||||
else if (stream->next_buf_toisp)
|
||||
active_buf = stream->next_buf_toisp;
|
||||
|
||||
stream->next_buf_toisp = NULL;
|
||||
stream->curr_buf_toisp = NULL;
|
||||
}
|
||||
if (stream->lack_buf_cnt == 2) {
|
||||
stream->to_stop_dma = RKCIF_DMAEN_BY_ISP;
|
||||
rkcif_stop_dma_capture(stream);
|
||||
}
|
||||
if (active_buf) {
|
||||
if (stream->frame_idx == 1)
|
||||
@@ -2078,8 +2092,6 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
stream->last_frame_idx = stream->frame_idx;
|
||||
if (dev->hdr.hdr_mode == NO_HDR) {
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
if (dev->is_support_tools && stream->tools_vdev)
|
||||
rkcif_rdbk_with_tools(stream, active_buf);
|
||||
atomic_dec(&stream->buf_cnt);
|
||||
} else {
|
||||
rkcif_rdbk_frame_end_toisp(stream, active_buf);
|
||||
@@ -2091,8 +2103,8 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
stream->id,
|
||||
stream->frame_idx - 1);
|
||||
}
|
||||
if (dev->is_support_tools && stream->tools_vdev && stream->curr_buf_toisp)
|
||||
rkcif_rdbk_with_tools(stream, stream->curr_buf_toisp);
|
||||
if (dev->is_support_tools && stream->tools_vdev && active_buf)
|
||||
rkcif_rdbk_with_tools(stream, active_buf);
|
||||
}
|
||||
|
||||
out_get_buf:
|
||||
@@ -2152,6 +2164,7 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
int frame_phase = 0;
|
||||
int frame_phase_next = 0;
|
||||
bool is_early_update = false;
|
||||
bool is_dual_update = false;
|
||||
|
||||
if (stream->curr_buf_toisp != stream->next_buf_toisp) {
|
||||
if (dev->rdbk_debug > 2 &&
|
||||
@@ -2169,19 +2182,19 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
vblank_ns = vblank * dev->sensor_linetime;
|
||||
cur_time = ktime_get_ns();
|
||||
|
||||
frame_phase = stream->frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
CIF_CSI_FRAME0_READY : CIF_CSI_FRAME1_READY;
|
||||
frame_phase_next = stream->frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
CIF_CSI_FRAME1_READY : CIF_CSI_FRAME0_READY;
|
||||
if (dev->chip_id > CHIP_RK3568_CIF &&
|
||||
dev->hdr.hdr_mode == NO_HDR &&
|
||||
cur_time - stream->readout.fe_timestamp < (vblank_ns - 500000) &&
|
||||
stream->lack_buf_cnt == 2 &&
|
||||
stream->frame_idx > stream->last_frame_idx) {
|
||||
stream->frame_idx > stream->last_frame_idx)
|
||||
is_early_update = true;
|
||||
frame_phase = stream->frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
CIF_CSI_FRAME1_READY : CIF_CSI_FRAME0_READY;
|
||||
frame_phase_next = stream->frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
CIF_CSI_FRAME0_READY : CIF_CSI_FRAME1_READY;
|
||||
} else {
|
||||
frame_phase = stream->frame_phase;
|
||||
}
|
||||
else if (!stream->dma_en)
|
||||
is_dual_update = true;
|
||||
|
||||
if (dev->rdbk_debug > 2 &&
|
||||
stream->frame_idx < 15)
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
@@ -2295,6 +2308,29 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
} else {
|
||||
rkcif_write_register(dev, frm_addr_y, buff_addr_y);
|
||||
}
|
||||
} else if (is_dual_update) {
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CCP2) {
|
||||
frm_addr_y = frame_phase_next & CIF_CSI_FRAME0_READY ?
|
||||
get_reg_index_of_frm0_y_addr(stream->id) :
|
||||
get_reg_index_of_frm1_y_addr(stream->id);
|
||||
} else {
|
||||
frm_addr_y = frame_phase_next & CIF_CSI_FRAME0_READY ?
|
||||
get_dvp_reg_index_of_frm0_y_addr(stream->id) :
|
||||
get_dvp_reg_index_of_frm1_y_addr(stream->id);
|
||||
}
|
||||
if (frame_phase == CIF_CSI_FRAME0_READY)
|
||||
stream->next_buf_toisp = stream->curr_buf_toisp;
|
||||
else
|
||||
stream->curr_buf_toisp = stream->next_buf_toisp;
|
||||
buff_addr_y = stream->curr_buf_toisp->dummy.dma_addr;
|
||||
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
rkcif_write_buff_addr_multi_dev_combine(stream, frm_addr_y, 0,
|
||||
buff_addr_y, 0, false);
|
||||
} else {
|
||||
rkcif_write_register(dev, frm_addr_y, buff_addr_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2675,7 +2711,8 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
||||
} else {
|
||||
dbufs = &stream->curr_buf_toisp->dbufs;
|
||||
}
|
||||
rkcif_s_rx_buffer(dev, dbufs);
|
||||
if (dbufs)
|
||||
rkcif_s_rx_buffer(dev, dbufs);
|
||||
if (stream->curr_buf && stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
||||
stream->curr_buf = NULL;
|
||||
if (stream->buf_replace_cnt)
|
||||
@@ -4690,12 +4727,14 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
|
||||
buf->dbufs.is_uncompact = false;
|
||||
else
|
||||
buf->dbufs.is_uncompact = true;
|
||||
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && i == 0) {
|
||||
if (priv && i == 0) {
|
||||
buf->dbufs.is_first = true;
|
||||
rkcif_s_rx_buffer(dev, &buf->dbufs);
|
||||
if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
|
||||
rkcif_s_rx_buffer(dev, &buf->dbufs);
|
||||
}
|
||||
i++;
|
||||
if (!dev->is_thunderboot && i >= buf_num) {
|
||||
priv->buf_num = buf_num;
|
||||
break;
|
||||
} else if (i >= RKISP_VICAP_BUF_CNT_MAX) {
|
||||
priv->buf_num = i;
|
||||
@@ -10263,6 +10302,247 @@ static bool rkcif_check_buffer_prepare(struct rkcif_stream *stream)
|
||||
return is_update;
|
||||
}
|
||||
|
||||
static int rkcif_subdevs_set_power(struct rkcif_device *cif_dev, int on)
|
||||
{
|
||||
struct sditf_priv *priv = cif_dev->sditf[0];
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
|
||||
if (cif_dev->terminal_sensor.sd)
|
||||
ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd,
|
||||
core, s_power, on);
|
||||
if (priv && priv->is_combine_mode && cif_dev->sditf_cnt <= RKCIF_MAX_SDITF) {
|
||||
for (i = 0; i < cif_dev->sditf_cnt; i++) {
|
||||
if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd)
|
||||
v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, core,
|
||||
s_power, on);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rkcif_subdevs_set_stream(struct rkcif_device *cif_dev, int on)
|
||||
{
|
||||
struct rkcif_pipeline *p = &cif_dev->pipe;
|
||||
struct sditf_priv *priv = cif_dev->sditf[0];
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < p->num_subdevs; i++) {
|
||||
ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
|
||||
if (ret)
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"%s:stream %s subdev:%s failed\n",
|
||||
__func__, on ? "on" : "off", p->subdevs[i]->name);
|
||||
}
|
||||
|
||||
if (priv && priv->is_combine_mode && cif_dev->sditf_cnt <= RKCIF_MAX_SDITF) {
|
||||
for (i = 0; i < cif_dev->sditf_cnt; i++) {
|
||||
if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd) {
|
||||
ret = v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, video, s_stream, on);
|
||||
if (ret)
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"%s:stream %s subdev:%s failed\n",
|
||||
__func__, on ? "on" : "off",
|
||||
cif_dev->sditf[i]->sensor_sd->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rkcif_stream_suspend(struct rkcif_device *cif_dev, int mode)
|
||||
{
|
||||
struct rkcif_stream *stream = NULL;
|
||||
struct rkcif_resume_info *resume_info = &cif_dev->reset_work.resume_info;
|
||||
struct sditf_priv *priv = cif_dev->sditf[0];
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
int sof_cnt = 0;
|
||||
int on = 0;
|
||||
int suspend_cnt = 0;
|
||||
|
||||
mutex_lock(&cif_dev->stream_lock);
|
||||
|
||||
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && mode == RKCIF_RESUME_CIF)
|
||||
goto out_suspend;
|
||||
|
||||
for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
|
||||
stream = &cif_dev->stream[i];
|
||||
|
||||
if (stream->state == RKCIF_STATE_STREAMING) {
|
||||
suspend_cnt++;
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"stream[%d] stopping\n", stream->id);
|
||||
if (stream->dma_en) {
|
||||
stream->stopping = true;
|
||||
ret = wait_event_timeout(stream->wq_stopped,
|
||||
stream->state != RKCIF_STATE_STREAMING,
|
||||
msecs_to_jiffies(500));
|
||||
if (!ret) {
|
||||
rkcif_stream_stop(stream);
|
||||
stream->stopping = false;
|
||||
}
|
||||
} else {
|
||||
rkcif_stream_stop(stream);
|
||||
}
|
||||
|
||||
if (stream->id == RKCIF_STREAM_MIPI_ID0) {
|
||||
sof_cnt = rkcif_get_sof(cif_dev);
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"%s: stream[%d] sync frmid & csi_sof, frm_id:%d, csi_sof:%d\n",
|
||||
__func__,
|
||||
stream->id,
|
||||
stream->frame_idx,
|
||||
sof_cnt);
|
||||
|
||||
resume_info->frm_sync_seq = stream->frame_idx;
|
||||
}
|
||||
|
||||
stream->state = RKCIF_STATE_RESET_IN_STREAMING;
|
||||
stream->is_fs_fe_not_paired = false;
|
||||
stream->fs_cnt_in_single_frame = 0;
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"%s stop stream[%d] in streaming, frm_id:%d, csi_sof:%d\n",
|
||||
__func__, stream->id, stream->frame_idx, rkcif_get_sof(cif_dev));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rkcif_subdevs_set_power(cif_dev, on);
|
||||
|
||||
if (suspend_cnt == 0)
|
||||
goto out_suspend;
|
||||
|
||||
rkcif_subdevs_set_stream(cif_dev, on);
|
||||
|
||||
out_suspend:
|
||||
mutex_unlock(&cif_dev->stream_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
|
||||
{
|
||||
struct rkcif_stream *stream = NULL;
|
||||
struct sditf_priv *priv = cif_dev->sditf[0];
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
u32 capture_mode = 0;
|
||||
int on = 0;
|
||||
int resume_cnt = 0;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&cif_dev->stream_lock);
|
||||
|
||||
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)
|
||||
capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
|
||||
else
|
||||
capture_mode = RKCIF_STREAM_MODE_CAPTURE;
|
||||
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && mode == RKCIF_RESUME_CIF)
|
||||
goto out_resume;
|
||||
|
||||
for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
|
||||
stream = &cif_dev->stream[i];
|
||||
if (stream->state != RKCIF_STATE_RESET_IN_STREAMING)
|
||||
continue;
|
||||
|
||||
stream->fs_cnt_in_single_frame = 0;
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
if (!priv || priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ) {
|
||||
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
|
||||
if (stream->curr_buf == stream->next_buf) {
|
||||
if (stream->curr_buf)
|
||||
list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
|
||||
} else {
|
||||
if (stream->curr_buf)
|
||||
list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
|
||||
if (stream->next_buf)
|
||||
list_add_tail(&stream->next_buf->queue, &stream->buf_head);
|
||||
}
|
||||
stream->curr_buf = NULL;
|
||||
stream->next_buf = NULL;
|
||||
}
|
||||
} else {
|
||||
if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
|
||||
if (stream->curr_buf_toisp == stream->next_buf_toisp) {
|
||||
if (stream->curr_buf_toisp)
|
||||
list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
|
||||
} else {
|
||||
if (stream->curr_buf_toisp)
|
||||
list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
|
||||
if (stream->next_buf_toisp)
|
||||
list_add_tail(&stream->next_buf_toisp->list, &stream->rx_buf_head);
|
||||
}
|
||||
stream->curr_buf_toisp = NULL;
|
||||
stream->next_buf_toisp = NULL;
|
||||
} else {
|
||||
if (stream->curr_buf_toisp == stream->next_buf_toisp) {
|
||||
if (stream->curr_buf_toisp)
|
||||
list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
|
||||
} else {
|
||||
if (stream->curr_buf_toisp)
|
||||
list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
|
||||
if (stream->next_buf_toisp)
|
||||
list_add_tail(&stream->next_buf_toisp->list, &stream->rx_buf_head);
|
||||
}
|
||||
stream->curr_buf_toisp = NULL;
|
||||
stream->next_buf_toisp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
|
||||
if (capture_mode == RKCIF_STREAM_MODE_TOISP)
|
||||
sditf_change_to_online(priv);
|
||||
else
|
||||
sditf_disable_immediately(priv);
|
||||
|
||||
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);
|
||||
|
||||
stream->lack_buf_cnt = 0;
|
||||
if (cif_dev->active_sensor &&
|
||||
(cif_dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
|
||||
cif_dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY ||
|
||||
cif_dev->active_sensor->mbus.type == V4L2_MBUS_CCP2))
|
||||
ret = rkcif_csi_stream_start(stream, capture_mode);
|
||||
else
|
||||
ret = rkcif_stream_start(stream, capture_mode);
|
||||
if (ret)
|
||||
v4l2_err(&cif_dev->v4l2_dev, "%s:resume stream[%d] failed\n",
|
||||
__func__, stream->id);
|
||||
|
||||
resume_cnt++;
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"resume stream[%d], frm_idx:%d, csi_sof:%d\n",
|
||||
stream->id, stream->frame_idx,
|
||||
rkcif_get_sof(cif_dev));
|
||||
}
|
||||
|
||||
on = 1;
|
||||
|
||||
rkcif_subdevs_set_power(cif_dev, on);
|
||||
|
||||
if (resume_cnt == 0)
|
||||
goto out_resume;
|
||||
|
||||
rkcif_subdevs_set_stream(cif_dev, on);
|
||||
|
||||
if (cif_dev->chip_id < CHIP_RK3588_CIF)
|
||||
rkcif_start_luma(&cif_dev->luma_vdev,
|
||||
cif_dev->stream[RKCIF_STREAM_MIPI_ID0].cif_fmt_in);
|
||||
out_resume:
|
||||
mutex_unlock(&cif_dev->stream_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rkcif_err_print_work(struct work_struct *work)
|
||||
{
|
||||
struct rkcif_err_state_work *err_state_work = container_of(work,
|
||||
@@ -10322,10 +10602,18 @@ void rkcif_err_print_work(struct work_struct *work)
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"stream[3], frm0/frm1 end simultaneously,frm id:%d, cnt %llu\n",
|
||||
dev->stream[3].frame_idx, dev->irq_stats.trig_simult_cnt[3]);
|
||||
if (err_state & RKCIF_ERR_SIZE)
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"ERROR: csi size err, intstat:0x%x, lastline:0x%x, cnt %llu\n",
|
||||
intstat, lastline, dev->irq_stats.csi_size_err_cnt);
|
||||
if (err_state & RKCIF_ERR_SIZE) {
|
||||
if (dev->chip_id >= CHIP_RK3588_CIF)
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"ERROR: csi size err, intstat:0x%x, size:0x%x,0x%x,0x%x,0x%x, cnt %llu\n",
|
||||
intstat, err_state_work->size_id0, err_state_work->size_id1,
|
||||
err_state_work->size_id2, err_state_work->size_id3,
|
||||
dev->irq_stats.csi_size_err_cnt);
|
||||
else
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"ERROR: csi size err, intstat:0x%x, lastline:0x%x, cnt %llu\n",
|
||||
intstat, lastline, dev->irq_stats.csi_size_err_cnt);
|
||||
}
|
||||
if (err_state & RKCIF_ERR_OVERFLOW)
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"ERROR: csi fifo overflow, intstat:0x%x, lastline:0x%x, cnt %llu\n",
|
||||
@@ -10379,13 +10667,22 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
if (intstat) {
|
||||
rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT, intstat);
|
||||
v4l2_dbg(2, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"intstat 0x%x\n",
|
||||
intstat);
|
||||
"intstat 0x%x\n", intstat);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (intstat & CSI_SIZE_ERR) {
|
||||
if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
|
||||
cif_dev->err_state_work.size_id0 = rkcif_read_register(cif_dev,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID0);
|
||||
cif_dev->err_state_work.size_id1 = rkcif_read_register(cif_dev,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID1);
|
||||
cif_dev->err_state_work.size_id2 = rkcif_read_register(cif_dev,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID2);
|
||||
cif_dev->err_state_work.size_id3 = rkcif_read_register(cif_dev,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID3);
|
||||
}
|
||||
cif_dev->irq_stats.csi_size_err_cnt++;
|
||||
cif_dev->err_state |= RKCIF_ERR_SIZE;
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
|
||||
@@ -2211,6 +2211,21 @@ static int rkcif_plat_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rkcif_runtime_prepare(struct device *dev)
|
||||
{
|
||||
struct rkcif_device *cif_dev = dev_get_drvdata(dev);
|
||||
|
||||
rkcif_stream_suspend(cif_dev, RKCIF_RESUME_CIF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __maybe_unused rkcif_runtime_complete(struct device *dev)
|
||||
{
|
||||
struct rkcif_device *cif_dev = dev_get_drvdata(dev);
|
||||
|
||||
rkcif_stream_resume(cif_dev, RKCIF_RESUME_CIF);
|
||||
}
|
||||
|
||||
static int __maybe_unused rkcif_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rkcif_device *cif_dev = dev_get_drvdata(dev);
|
||||
@@ -2281,8 +2296,8 @@ late_initcall(rkcif_clr_unready_dev);
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops rkcif_plat_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
pm_runtime_force_resume)
|
||||
.prepare = rkcif_runtime_prepare,
|
||||
.complete = rkcif_runtime_complete,
|
||||
SET_RUNTIME_PM_OPS(rkcif_runtime_suspend, rkcif_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
|
||||
@@ -792,6 +792,15 @@ struct rkcif_err_state_work {
|
||||
u32 intstat;
|
||||
u32 lastline;
|
||||
u32 lastpixel;
|
||||
u32 size_id0;
|
||||
u32 size_id1;
|
||||
u32 size_id2;
|
||||
u32 size_id3;
|
||||
};
|
||||
|
||||
enum rkcif_resume_user {
|
||||
RKCIF_RESUME_CIF,
|
||||
RKCIF_RESUME_ISP,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -968,5 +977,7 @@ void rkcif_rockit_dev_init(struct rkcif_device *dev);
|
||||
void rkcif_rockit_dev_deinit(void);
|
||||
|
||||
void rkcif_err_print_work(struct work_struct *work);
|
||||
int rkcif_stream_suspend(struct rkcif_device *cif_dev, int mode);
|
||||
int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -699,6 +699,10 @@ static const struct cif_reg rk3588_cif_regs[] = {
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
|
||||
[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
|
||||
|
||||
[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
|
||||
@@ -823,6 +827,10 @@ static const struct cif_reg rv1106_cif_regs[] = {
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
|
||||
[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
|
||||
[CIF_REG_LVDS_ID0_CTRL0] = CIF_REG(CIF_LVDS0_ID0_CTRL0),
|
||||
[CIF_REG_LVDS_ID1_CTRL0] = CIF_REG(CIF_LVDS0_ID1_CTRL0),
|
||||
@@ -942,6 +950,10 @@ static const struct cif_reg rk3562_cif_regs[] = {
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
|
||||
[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
|
||||
[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
|
||||
[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
|
||||
|
||||
[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
|
||||
@@ -1538,7 +1550,32 @@ static int __maybe_unused rkcif_runtime_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rkcif_sleep_suspend(struct device *dev)
|
||||
{
|
||||
struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
|
||||
|
||||
rkcif_disable_sys_clk(cif_hw);
|
||||
|
||||
return pinctrl_pm_select_sleep_state(dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused rkcif_sleep_resume(struct device *dev)
|
||||
{
|
||||
struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = pinctrl_pm_select_default_state(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rkcif_enable_sys_clk(cif_hw);
|
||||
rkcif_hw_soft_reset(cif_hw, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rkcif_plat_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(rkcif_sleep_suspend,
|
||||
rkcif_sleep_resume)
|
||||
SET_RUNTIME_PM_OPS(rkcif_runtime_suspend, rkcif_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
|
||||
@@ -145,6 +145,10 @@ enum cif_reg_index {
|
||||
CIF_REG_LVDS_ID1_CTRL0,
|
||||
CIF_REG_LVDS_ID2_CTRL0,
|
||||
CIF_REG_LVDS_ID3_CTRL0,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID0,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID1,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID2,
|
||||
CIF_REG_MIPI_FRAME_SIZE_ID3,
|
||||
CIF_REG_MIPI_ON_PAD,
|
||||
|
||||
CIF_REG_Y_STAT_CONTROL,
|
||||
@@ -421,6 +425,11 @@ enum cif_reg_index {
|
||||
#define CSI_MIPI0_EFFECT_CODE_ID3 0x1B8
|
||||
#define CSI_MIPI0_ON_PAD 0x1BC
|
||||
|
||||
#define CSI_MIPI0_FRAME_SIZE_ID0 0x1C0
|
||||
#define CSI_MIPI0_FRAME_SIZE_ID1 0x1C4
|
||||
#define CSI_MIPI0_FRAME_SIZE_ID2 0x1C8
|
||||
#define CSI_MIPI0_FRAME_SIZE_ID3 0x1CC
|
||||
|
||||
/* RV1106 CONTROL Registers Offset */
|
||||
#define CIF_LVDS0_ID0_CTRL0 0x1D0
|
||||
#define CIF_LVDS0_ID1_CTRL0 0x1D4
|
||||
|
||||
@@ -327,6 +327,7 @@ static void sditf_reinit_mode(struct sditf_priv *priv, struct rkisp_vicap_mode *
|
||||
__func__, mode->rdbk_mode, mode->name, priv->toisp_inf.link_mode);
|
||||
}
|
||||
|
||||
static void sditf_channel_disable(struct sditf_priv *priv, int user);
|
||||
static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct sditf_priv *priv = to_sditf_priv(sd);
|
||||
@@ -336,11 +337,14 @@ static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
struct v4l2_subdev *sensor_sd;
|
||||
int *pbuf_num = NULL;
|
||||
int ret = 0;
|
||||
int *on = NULL;
|
||||
|
||||
switch (cmd) {
|
||||
case RKISP_VICAP_CMD_MODE:
|
||||
mode = (struct rkisp_vicap_mode *)arg;
|
||||
mutex_lock(&cif_dev->stream_lock);
|
||||
memcpy(&priv->mode, mode, sizeof(*mode));
|
||||
mutex_unlock(&cif_dev->stream_lock);
|
||||
sditf_reinit_mode(priv, &priv->mode);
|
||||
if (priv->is_combine_mode)
|
||||
mode->input.merge_num = cif_dev->sditf_cnt;
|
||||
@@ -363,6 +367,22 @@ static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg);
|
||||
}
|
||||
break;
|
||||
case RKISP_VICAP_CMD_QUICK_STREAM:
|
||||
on = (int *)arg;
|
||||
if (*on) {
|
||||
rkcif_stream_resume(cif_dev, RKCIF_RESUME_ISP);
|
||||
} else {
|
||||
if (priv->toisp_inf.link_mode == TOISP0) {
|
||||
sditf_channel_disable(priv, 0);
|
||||
} else if (priv->toisp_inf.link_mode == TOISP1) {
|
||||
sditf_channel_disable(priv, 1);
|
||||
} else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
|
||||
sditf_channel_disable(priv, 0);
|
||||
sditf_channel_disable(priv, 1);
|
||||
}
|
||||
rkcif_stream_suspend(cif_dev, RKCIF_RESUME_ISP);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -382,6 +402,7 @@ static long sditf_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
struct rkmodule_hdr_cfg *hdr_cfg;
|
||||
int buf_num;
|
||||
int ret = 0;
|
||||
int on;
|
||||
|
||||
switch (cmd) {
|
||||
case RKISP_VICAP_CMD_MODE:
|
||||
@@ -414,6 +435,11 @@ static long sditf_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
}
|
||||
ret = sditf_ioctl(sd, cmd, hdr_cfg);
|
||||
return ret;
|
||||
case RKISP_VICAP_CMD_QUICK_STREAM:
|
||||
if (copy_from_user(&on, up, sizeof(int)))
|
||||
return -EFAULT;
|
||||
ret = sditf_ioctl(sd, cmd, &on);
|
||||
return ret;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -605,6 +631,21 @@ void sditf_change_to_online(struct sditf_priv *priv)
|
||||
cif_dev->wait_line_bak = 0;
|
||||
}
|
||||
|
||||
void sditf_disable_immediately(struct sditf_priv *priv)
|
||||
{
|
||||
struct rkcif_device *cif_dev = priv->cif_dev;
|
||||
u32 ctrl_val = 0x10101;
|
||||
|
||||
if (priv->toisp_inf.link_mode == TOISP0) {
|
||||
rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CTRL, ~ctrl_val);
|
||||
} else if (priv->toisp_inf.link_mode == TOISP1) {
|
||||
rkcif_write_register_and(cif_dev, CIF_REG_TOISP1_CTRL, ~ctrl_val);
|
||||
} else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
|
||||
rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CTRL, ~ctrl_val);
|
||||
rkcif_write_register_and(cif_dev, CIF_REG_TOISP1_CTRL, ~ctrl_val);
|
||||
}
|
||||
}
|
||||
|
||||
static void sditf_check_capture_mode(struct rkcif_device *cif_dev)
|
||||
{
|
||||
struct rkcif_device *dev = NULL;
|
||||
@@ -828,6 +869,10 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
|
||||
if (!is_free && (!dbufs->is_switch)) {
|
||||
list_add_tail(&rx_buf->list, &stream->rx_buf_head);
|
||||
rkcif_assign_check_buffer_update_toisp(stream);
|
||||
if (!stream->dma_en) {
|
||||
stream->to_en_dma = RKCIF_DMAEN_BY_ISP;
|
||||
rkcif_enable_dma_capture(stream, true);
|
||||
}
|
||||
if (cif_dev->rdbk_debug) {
|
||||
u32 offset = 0;
|
||||
|
||||
@@ -855,6 +900,9 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
|
||||
}
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
|
||||
if (!cif_dev->is_thunderboot)
|
||||
return 0;
|
||||
|
||||
if (dbufs->runtime_us && cif_dev->early_line == 0) {
|
||||
if (!cif_dev->sensor_linetime)
|
||||
cif_dev->sensor_linetime = rkcif_get_linetime(stream);
|
||||
|
||||
@@ -84,5 +84,6 @@ struct sditf_priv {
|
||||
|
||||
extern struct platform_driver rkcif_subdev_driver;
|
||||
void sditf_change_to_online(struct sditf_priv *priv);
|
||||
void sditf_disable_immediately(struct sditf_priv *priv);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user