diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 0d4ac1afe006..3a976fad466a 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -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: diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.c b/drivers/media/platform/rockchip/isp/isp_params_v35.c index 184e4695b50a..9b2a84b44c8e 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v35.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.c @@ -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; + } } } diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 0217f8ebd5c6..27ca6de91a6b 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -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;