media: rockchip: fix isp no work due to irq_ends_mask error

Change-Id: I62dc2383720adb03b8ade6affbea7ee50ffa4427
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2023-02-27 15:59:07 +08:00
parent acd9ec5a6d
commit 7ca7e7ce1f
4 changed files with 40 additions and 57 deletions

View File

@@ -1388,15 +1388,8 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
static int rkisp_start(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
bool is_update = false;
int ret;
if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) {
is_update = (stream->id == RKISP_STREAM_MP) ?
!dev->cap_dev.stream[RKISP_STREAM_SP].streaming :
!dev->cap_dev.stream[RKISP_STREAM_MP].streaming;
}
if (stream->ops->set_data_path)
stream->ops->set_data_path(stream);
ret = stream->ops->config_mi(stream);
@@ -1406,9 +1399,6 @@ static int rkisp_start(struct rkisp_stream *stream)
stream->ops->enable_mi(stream);
if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP)
hdr_config_dmatx(dev);
if (is_update)
dev->irq_ends_mask |=
(stream->id == RKISP_STREAM_MP) ? ISP_FRAME_MP : ISP_FRAME_SP;
stream->streaming = true;
return 0;
@@ -1965,16 +1955,12 @@ void rkisp_mi_v21_isr(u32 mis_val, struct rkisp_device *dev)
stream = &dev->cap_dev.stream[RKISP_STREAM_MP];
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_MP;
else
dev->irq_ends_mask |= ISP_FRAME_MP;
rkisp_check_idle(dev, ISP_FRAME_MP);
}
if (mis_val & CIF_MI_SP_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_SP];
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_SP;
else
dev->irq_ends_mask |= ISP_FRAME_SP;
rkisp_check_idle(dev, ISP_FRAME_SP);
}
}

View File

@@ -1029,11 +1029,13 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
bool is_wait = dev->hw_dev->is_shutdown ? false : true;
stream->stopping = true;
stream->ops->disable_mi(stream);
if (dev->hw_dev->is_single)
stream->ops->disable_mi(stream);
if (IS_HDR_RDBK(dev->rd_mode)) {
spin_lock_irqsave(&dev->hw_dev->rdbk_lock, lock_flags);
if (dev->hw_dev->cur_dev_id != dev->dev_id || dev->hw_dev->is_idle) {
is_wait = false;
stream->ops->disable_mi(stream);
/* force update to close */
if (dev->hw_dev->is_single)
stream_self_update(stream);
@@ -1074,8 +1076,6 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
*/
static int rkisp_start(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
bool is_update = atomic_read(&dev->cap_dev.refcnt) > 1 ? false : true;
int ret;
if (stream->ops->set_data_path)
@@ -1085,8 +1085,6 @@ static int rkisp_start(struct rkisp_stream *stream)
return ret;
stream->ops->enable_mi(stream);
if (is_update)
dev->irq_ends_mask |= get_stream_irq_mask(stream);
stream->streaming = true;
return 0;
@@ -1721,32 +1719,24 @@ void rkisp_mi_v30_isr(u32 mis_val, struct rkisp_device *dev)
stream = &dev->cap_dev.stream[RKISP_STREAM_MP];
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_MP;
else
dev->irq_ends_mask |= ISP_FRAME_MP;
rkisp_check_idle(dev, ISP_FRAME_MP);
}
if (mis_val & ISP3X_MI_SP_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_SP];
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_SP;
else
dev->irq_ends_mask |= ISP_FRAME_SP;
rkisp_check_idle(dev, ISP_FRAME_SP);
}
if (mis_val & ISP3X_MI_MPFBC_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_FBC];
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_MPFBC;
else
dev->irq_ends_mask |= ISP_FRAME_MPFBC;
rkisp_check_idle(dev, ISP_FRAME_MPFBC);
}
if (mis_val & ISP3X_MI_BP_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_BP];
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_BP;
else
dev->irq_ends_mask |= ISP_FRAME_BP;
rkisp_check_idle(dev, ISP_FRAME_BP);
}
}

View File

@@ -1438,12 +1438,14 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
stream->stopping = true;
stream->is_pause = false;
if (stream->ops->disable_mi)
if (stream->ops->disable_mi && dev->hw_dev->is_single)
stream->ops->disable_mi(stream);
if (IS_HDR_RDBK(dev->rd_mode)) {
spin_lock_irqsave(&dev->hw_dev->rdbk_lock, lock_flags);
if (dev->hw_dev->cur_dev_id != dev->dev_id || dev->hw_dev->is_idle) {
is_wait = false;
if (stream->ops->disable_mi)
stream->ops->disable_mi(stream);
/* force update to close */
if (dev->hw_dev->is_single)
stream_self_update(stream);
@@ -1489,7 +1491,6 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
static int rkisp_start(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
bool is_update = atomic_read(&dev->cap_dev.refcnt) > 1 ? false : true;
int ret;
if (stream->ops->set_data_path)
@@ -1504,10 +1505,7 @@ static int rkisp_start(struct rkisp_stream *stream)
if (stream->ops->enable_mi && !stream->is_pause)
stream->ops->enable_mi(stream);
if (is_update)
dev->irq_ends_mask |= get_stream_irq_mask(stream);
stream->streaming = true;
return 0;
}
@@ -2275,26 +2273,20 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev)
if (mis_val & ISP3X_MI_MP_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_MP];
if (!stream->streaming || stream->is_pause)
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_MP;
else
dev->irq_ends_mask |= ISP_FRAME_MP;
rkisp_check_idle(dev, ISP_FRAME_MP);
}
if (mis_val & ISP3X_MI_SP_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_SP];
if (!stream->streaming || stream->is_pause)
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_SP;
else
dev->irq_ends_mask |= ISP_FRAME_SP;
rkisp_check_idle(dev, ISP_FRAME_SP);
}
if (mis_val & ISP3X_MI_BP_FRAME) {
stream = &dev->cap_dev.stream[RKISP_STREAM_BP];
if (!stream->streaming || stream->is_pause)
if (!stream->streaming)
dev->irq_ends_mask &= ~ISP_FRAME_BP;
else
dev->irq_ends_mask |= ISP_FRAME_BP;
rkisp_check_idle(dev, ISP_FRAME_BP);
}
}

View File

@@ -703,22 +703,6 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
dev->multi_mode, dev->multi_index, val);
}
is_upd = true;
/* if output stream enable, wait it end */
val = rkisp_read(dev, CIF_MI_CTRL_SHD, true);
if (val & CIF_MI_CTRL_SHD_MP_OUT_ENABLED &&
!(dev->irq_ends_mask & ISP_FRAME_MP))
dev->irq_ends_mask |= ISP_FRAME_MP;
if (val & CIF_MI_CTRL_SHD_SP_OUT_ENABLED &&
!(dev->irq_ends_mask & ISP_FRAME_SP))
dev->irq_ends_mask |= ISP_FRAME_SP;
if (dev->isp_ver == ISP_V30 &&
!(dev->irq_ends_mask & ISP_FRAME_MPFBC) &&
rkisp_read(dev, ISP3X_MPFBC_CTRL, true) & ISP3X_MPFBC_EN_SHD)
dev->irq_ends_mask |= ISP_FRAME_MPFBC;
if (dev->isp_ver == ISP_V32 &&
!(dev->irq_ends_mask & ISP_FRAME_BP) &&
rkisp_read(dev, ISP32_MI_WR_CTRL2_SHD, true) & ISP32_BP_EN_OUT_SHD)
dev->irq_ends_mask |= ISP_FRAME_BP;
}
if (dev->isp_ver > ISP_V20)
@@ -779,6 +763,31 @@ run_next:
if (is_3dlut_upd)
rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 1, true, hw->is_unite);
/* if output stream enable, wait it end */
val = rkisp_read(dev, CIF_MI_CTRL_SHD, true);
if (val & CIF_MI_CTRL_SHD_MP_OUT_ENABLED)
dev->irq_ends_mask |= ISP_FRAME_MP;
else
dev->irq_ends_mask &= ~ISP_FRAME_MP;
if (val & CIF_MI_CTRL_SHD_SP_OUT_ENABLED)
dev->irq_ends_mask |= ISP_FRAME_SP;
else
dev->irq_ends_mask &= ~ISP_FRAME_SP;
if ((dev->isp_ver == ISP_V20 &&
rkisp_read(dev, ISP_MPFBC_CTRL, true) & SW_MPFBC_EN) ||
(dev->isp_ver == ISP_V30 &&
rkisp_read(dev, ISP3X_MPFBC_CTRL, true) & ISP3X_MPFBC_EN_SHD))
dev->irq_ends_mask |= ISP_FRAME_MPFBC;
else
dev->irq_ends_mask &= ~ISP_FRAME_MPFBC;
if ((dev->isp_ver == ISP_V30 &&
rkisp_read(dev, ISP3X_BP_ENABLE, true) & ISP3X_BP_ENABLE) ||
(dev->isp_ver == ISP_V32 &&
rkisp_read(dev, ISP32_MI_WR_CTRL2_SHD, true) & ISP32_BP_EN_OUT_SHD))
dev->irq_ends_mask |= ISP_FRAME_BP;
else
dev->irq_ends_mask &= ~ISP_FRAME_BP;
val = rkisp_read(dev, CSI2RX_CTRL0, true);
val &= ~SW_IBUF_OP_MODE(0xf);
tmp = SW_IBUF_OP_MODE(dev->rd_mode);
@@ -1019,6 +1028,8 @@ end:
schedule_work(&dev->rdbk_work);
else
rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL);
if (dev->isp_state == ISP_STOP)
wake_up(&dev->sync_onoff);
}
static void rkisp_set_state(u32 *state, u32 val)
@@ -2826,6 +2837,10 @@ static int rkisp_isp_sd_s_stream(struct v4l2_subdev *sd, int on)
wake_up(&s->done);
}
}
wait_event_timeout(isp_dev->sync_onoff,
isp_dev->isp_state & ISP_STOP ||
!IS_HDR_RDBK(isp_dev->rd_mode),
msecs_to_jiffies(50));
rkisp_isp_stop(isp_dev);
atomic_dec(&hw_dev->refcnt);
rkisp_params_stream_stop(&isp_dev->params_vdev);