mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
media: rockchip: isp: aiisp switch for offline mode
Change-Id: I4e72621acf57d4497cb53b905e9ec75a23f558cd Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -351,8 +351,7 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p,
|
||||
rkisp_csi_config_patch(dev, false);
|
||||
dev->is_aiisp_sync = false;
|
||||
if (dev->is_aiisp_en &&
|
||||
((dev->isp_ver == ISP_V35 && !hw->is_single) ||
|
||||
(dev->isp_ver == ISP_V39 && (dev->isp_inp & INP_RAWRD2 || dev->is_rdbk_auto))))
|
||||
(!hw->is_single || IS_HDR_RDBK(dev->rd_mode)))
|
||||
dev->is_aiisp_sync = true;
|
||||
return 0;
|
||||
err:
|
||||
|
||||
@@ -6053,6 +6053,7 @@ rkisp_params_aiisp_event_v35(struct rkisp_isp_params_vdev *params_vdev, u32 irq)
|
||||
unsigned long lock_flags = 0;
|
||||
u32 h = dev->isp_sdev.out_crop.height;
|
||||
u32 val, wr_line, rd_line;
|
||||
bool is_event_queue = true;
|
||||
|
||||
if (sizeof(*ev_info) > sizeof(ev.u)) {
|
||||
v4l2_err(&dev->v4l2_dev, "aiisp_ev_info too large\n");
|
||||
@@ -6126,6 +6127,7 @@ rkisp_params_aiisp_event_v35(struct rkisp_isp_params_vdev *params_vdev, u32 irq)
|
||||
list_add_tail(&priv->pbuf_vpsl->queue, &priv->vpsl_list);
|
||||
priv->pbuf_vpsl = NULL;
|
||||
}
|
||||
is_event_queue = false;
|
||||
}
|
||||
|
||||
buf = priv->pbuf_vpsl;
|
||||
@@ -6142,7 +6144,8 @@ rkisp_params_aiisp_event_v35(struct rkisp_isp_params_vdev *params_vdev, u32 irq)
|
||||
ev_info->gain_index = buf->index;
|
||||
spin_unlock_irqrestore(&priv->buf_lock, lock_flags);
|
||||
}
|
||||
v4l2_event_queue(dev->isp_sdev.sd.devnode, &ev);
|
||||
if (is_event_queue)
|
||||
v4l2_event_queue(dev->isp_sdev.sd.devnode, &ev);
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s seq:%d height:%d idx(iir:%d gain:%d vpsl:%d aipre:%d aiisp:%d ysrc:%d ydst:%d)\n",
|
||||
ev.id ? "isp_be" : "isp_fe", ev_info->sequence, ev_info->height,
|
||||
@@ -6161,7 +6164,7 @@ rkisp_params_aiisp_start_v35(struct rkisp_isp_params_vdev *params_vdev,
|
||||
unsigned long lock_flags = 0;
|
||||
u32 val, aiisp_rd, seq = st->sequence;
|
||||
|
||||
if (!dev->is_aiisp_en)
|
||||
if (!dev->is_aiisp_en && !dev->is_aiisp_stop)
|
||||
return -EINVAL;
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"isp_be input seq:%d idx(iir:%d gain:%d vpsl:%d aipre:%d aiisp:%d)\n",
|
||||
@@ -6180,7 +6183,8 @@ rkisp_params_aiisp_start_v35(struct rkisp_isp_params_vdev *params_vdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rkisp_params_cfg(params_vdev, seq, RKISP_PARAMS_LAT);
|
||||
if (!dev->is_aiisp_stop)
|
||||
rkisp_params_cfg(params_vdev, seq, RKISP_PARAMS_LAT);
|
||||
|
||||
spin_lock_irqsave(&priv->buf_lock, lock_flags);
|
||||
buf = &priv->buf_bay3d_iir[st->iir_index];
|
||||
@@ -6244,6 +6248,11 @@ rkisp_params_aiisp_start_v35(struct rkisp_isp_params_vdev *params_vdev,
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->buf_lock, lock_flags);
|
||||
|
||||
if (dev->is_aiisp_stop) {
|
||||
dev->hw_dev->is_be_idle = true;
|
||||
rkisp_params_aiisp_event_v35(params_vdev, ISP3X_OUT_FRM_QUARTER);
|
||||
return -EINVAL;
|
||||
}
|
||||
val = params_vdev->is_hdr ? ISP35_B3DLDCH_RD_BASE_SHD : ISP3X_MI_RAW0_RD_BASE_SHD;
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"isp_be start seq:%d (%x %x | %x:%x %x:%x)\n",
|
||||
@@ -6336,6 +6345,9 @@ rkisp_params_aiisp_switch_v35(struct rkisp_isp_params_vdev *params_vdev, bool on
|
||||
|
||||
val = ISP39_AIISP_LINECNT_DONE | ISP3X_OUT_FRM_QUARTER | ISP3X_BAY3D_FRM_END;
|
||||
rkisp_clear_bits(dev, CIF_ISP_IMSC, val, false);
|
||||
|
||||
if (IS_HDR_RDBK(dev->rd_mode))
|
||||
dev->irq_ends_mask &= ~(ISP_FRAME_BNR | ISP_FRAME_VPSL);
|
||||
} else {
|
||||
val = rkisp_read(dev, ISP3X_ISP_CTRL1, false);
|
||||
val |= ISP35_BAYER_PAT_FE(params_vdev->raw_type) | ISP35_BAYER_UPD_FE_EN;
|
||||
@@ -6373,6 +6385,10 @@ rkisp_params_aiisp_switch_v35(struct rkisp_isp_params_vdev *params_vdev, bool on
|
||||
rkisp_write(dev, ISP35_AI_CTRL, val, false);
|
||||
|
||||
params_vdev->cur_fe_frame_id = params_vdev->cur_frame_id;
|
||||
if (IS_HDR_RDBK(dev->rd_mode)) {
|
||||
dev->is_first_frame = true;
|
||||
dev->irq_ends_mask = ISP_FRAME_BNR | ISP_FRAME_VPSL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1018,7 +1018,7 @@ run_next:
|
||||
cur_frame_id, dma2frm + 1, val, is_try);
|
||||
if (!hw->is_shutdown) {
|
||||
rkisp_unite_write(dev, CSI2RX_CTRL0, val, true);
|
||||
if (dev->is_aiisp_sync && !dev->is_first_frame) {
|
||||
if (dev->is_aiisp_en && dev->is_aiisp_sync && !dev->is_first_frame) {
|
||||
dev->irq_ends_mask |= ISP_FRAME_END;
|
||||
if (dev->isp_ver == ISP_V39) {
|
||||
val = rkisp_read(dev, ISP3X_MI_RD_CTRL2, false);
|
||||
@@ -1159,10 +1159,11 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
|
||||
goto end;
|
||||
if (isp->is_aiisp_sync && !isp->is_first_frame) {
|
||||
rkisp_rdbk_aiisp_event(isp, T_CMD_LEN, &len[id]);
|
||||
if (len[id])
|
||||
is_aiisp_ready = true;
|
||||
/* wait isp_be frame input */
|
||||
if (len[id] == 0)
|
||||
if (len[id] == 0 && isp->is_aiisp_en)
|
||||
goto end;
|
||||
is_aiisp_ready = true;
|
||||
}
|
||||
v4l2_dbg(2, rkisp_debug, &isp->v4l2_dev,
|
||||
"trigger fifo len:%d\n", max);
|
||||
@@ -1396,6 +1397,7 @@ end:
|
||||
if (dev->is_wait_aiq &&
|
||||
(dev->unite_div < ISP_UNITE_DIV2 || dev->unite_index == ISP_UNITE_RIGHT))
|
||||
return;
|
||||
rkisp_config_aiisp(dev);
|
||||
if (dev->hw_dev->is_dvfs)
|
||||
schedule_work(&dev->rdbk_work);
|
||||
else
|
||||
@@ -3967,7 +3969,7 @@ static void rkisp_config_aiisp(struct rkisp_device *dev)
|
||||
irq = ISP39_AIISP_LINECNT_DONE;
|
||||
if (dev->aiisp_cfg.rd_linecnt)
|
||||
irq |= ISP3X_OUT_FRM_QUARTER;
|
||||
|
||||
/* init aiisp stop */
|
||||
if (!(dev->isp_state & ISP_START) && dev->is_aiisp_stop)
|
||||
goto unlock;
|
||||
|
||||
@@ -3977,14 +3979,19 @@ static void rkisp_config_aiisp(struct rkisp_device *dev)
|
||||
dev->aiisp_stop_seq = dev->dmarx_dev.cur_frame.id;
|
||||
goto unlock;
|
||||
} else {
|
||||
dev->is_aiisp_en = false;
|
||||
irq = 0;
|
||||
dev->is_aiisp_en = false;
|
||||
dev->is_aiisp_stop = true;
|
||||
if (dev->params_vdev.ops->aiisp_switch)
|
||||
dev->params_vdev.ops->aiisp_switch(&dev->params_vdev, false);
|
||||
}
|
||||
} else if (!dev->is_aiisp_en && dev->aiisp_cfg.mode) {
|
||||
dev->is_aiisp_en = true;
|
||||
dev->is_aiisp_stop = false;
|
||||
if (dev->params_vdev.ops->aiisp_switch)
|
||||
dev->params_vdev.ops->aiisp_switch(&dev->params_vdev, true);
|
||||
if (!dev->hw_dev->is_single || IS_HDR_RDBK(dev->rd_mode))
|
||||
dev->is_aiisp_sync = true;
|
||||
}
|
||||
|
||||
if (dev->is_aiisp_en) {
|
||||
@@ -4027,19 +4034,32 @@ static int rkisp_set_aiisp_linecnt(struct rkisp_device *dev,
|
||||
struct rkisp_aiisp_cfg *cfg)
|
||||
{
|
||||
unsigned long lock_flags = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (dev->isp_ver != ISP_V39 && dev->isp_ver != ISP_V35)
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s mode:%d wr:%d rd:%d wr_mode:%d\n", __func__,
|
||||
cfg->mode, cfg->wr_linecnt, cfg->rd_linecnt, cfg->wr_mode);
|
||||
spin_lock_irqsave(&dev->aiisp_lock, lock_flags);
|
||||
if (!(dev->isp_state & ISP_START)) {
|
||||
if (!cfg->mode && cfg->wr_linecnt && cfg->rd_linecnt)
|
||||
if (!cfg->mode && cfg->wr_linecnt && cfg->rd_linecnt) {
|
||||
/* TODO support multi-sensor */
|
||||
if (!dev->hw_dev->is_single) {
|
||||
dev_err(dev->dev,
|
||||
"aibnr no support dynamic switch for multi-sensor now\n");
|
||||
goto unlock;
|
||||
}
|
||||
dev->is_aiisp_stop = true;
|
||||
}
|
||||
dev->is_aiisp_en = !!cfg->mode;
|
||||
}
|
||||
dev->is_aiisp_upd = true;
|
||||
dev->aiisp_cfg = *cfg;
|
||||
ret = 0;
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&dev->aiisp_lock, lock_flags);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rkisp_get_aiisp_linecnt(struct rkisp_device *dev,
|
||||
@@ -4135,7 +4155,7 @@ static int rkisp_rdbk_aiisp_event(struct rkisp_device *dev, u32 cmd, void *arg)
|
||||
stream->ops->push_buf(stream);
|
||||
}
|
||||
|
||||
if (!dev->is_aiisp_en)
|
||||
if (!dev->is_aiisp_en && !dev->is_aiisp_stop)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&dev->rdbk_lock, lock_flags);
|
||||
@@ -4163,7 +4183,8 @@ static int rkisp_rdbk_aiisp_event(struct rkisp_device *dev, u32 cmd, void *arg)
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->rdbk_lock, lock_flags);
|
||||
|
||||
if (dev->is_aiisp_sync && arg && cmd == T_CMD_QUEUE) {
|
||||
if (dev->is_aiisp_en && dev->is_aiisp_sync &&
|
||||
arg && cmd == T_CMD_QUEUE) {
|
||||
if (dev->hw_dev->is_idle)
|
||||
rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, NULL);
|
||||
goto end;
|
||||
|
||||
Reference in New Issue
Block a user