diff --git a/drivers/media/platform/rockchip/ispp/common.c b/drivers/media/platform/rockchip/ispp/common.c index 5bba87195b12..465a4d83d6c4 100644 --- a/drivers/media/platform/rockchip/ispp/common.c +++ b/drivers/media/platform/rockchip/ispp/common.c @@ -366,6 +366,7 @@ static void rkispp_queue_dmabuf(struct rkispp_hw_dev *hw, struct rkisp_ispp_buf ispp = hw->ispp[buf->index]; vdev = &ispp->stream_vdev; val = (vdev->module_ens & ISPP_MODULE_TNR) ? ISPP_MODULE_TNR : ISPP_MODULE_NR; + rkispp_params_cfg(&ispp->params_vdev, buf->frame_id); rkispp_module_work_event(ispp, buf, NULL, val, false); } diff --git a/drivers/media/platform/rockchip/ispp/params.c b/drivers/media/platform/rockchip/ispp/params.c index 1911806aa614..205c48b00058 100644 --- a/drivers/media/platform/rockchip/ispp/params.c +++ b/drivers/media/platform/rockchip/ispp/params.c @@ -353,16 +353,6 @@ static void nr_enable(struct rkispp_params_vdev *params_vdev, bool en, SW_UVNR_BIG_EN | SW_NR_EN, val); } -static bool is_nr_enable(struct rkispp_params_vdev *params_vdev) -{ - u32 cur_en; - - cur_en = rkispp_read(params_vdev->dev, RKISPP_NR_UVNR_CTRL_PARA); - cur_en &= SW_NR_EN; - - return (!!cur_en); -} - static void shp_config(struct rkispp_params_vdev *params_vdev, struct rkispp_sharp_config *arg) { @@ -515,16 +505,6 @@ static void shp_enable(struct rkispp_params_vdev *params_vdev, bool en, SW_SHP_EDGE_AVG_EN | SW_SHP_EN, val); } -static bool is_shp_enable(struct rkispp_params_vdev *params_vdev) -{ - u32 cur_en; - - cur_en = rkispp_read(params_vdev->dev, RKISPP_SHARP_CORE_CTRL); - cur_en &= SW_SHP_EN; - - return (!!cur_en); -} - static void fec_config(struct rkispp_params_vdev *params_vdev, struct rkispp_fec_config *arg) { @@ -607,19 +587,6 @@ static void fec_enable(struct rkispp_params_vdev *params_vdev, bool en) rkispp_set_bits(params_vdev->dev, RKISPP_FEC_CORE_CTRL, SW_FEC_EN, en); } -static bool is_fec_enable(struct rkispp_params_vdev *params_vdev) -{ - u32 cur_en; - - if (params_vdev->dev->hw_dev->is_fec_ext) - return false; - - cur_en = rkispp_read(params_vdev->dev, RKISPP_FEC_CORE_CTRL); - cur_en &= SW_FEC_EN; - - return (!!cur_en); -} - static void orb_config(struct rkispp_params_vdev *params_vdev, struct rkispp_orb_config *arg) { @@ -632,16 +599,6 @@ static void orb_enable(struct rkispp_params_vdev *params_vdev, bool en) rkispp_set_bits(params_vdev->dev, RKISPP_ORB_CORE_CTRL, SW_ORB_EN, en); } -static bool is_orb_enable(struct rkispp_params_vdev *params_vdev) -{ - u32 cur_en; - - cur_en = rkispp_read(params_vdev->dev, RKISPP_ORB_CORE_CTRL); - cur_en &= SW_ORB_EN; - - return (!!cur_en); -} - static int rkispp_params_enum_fmt_meta_out(struct file *file, void *priv, struct v4l2_fmtdesc *f) { @@ -803,18 +760,14 @@ static void rkispp_params_vb2_buf_queue(struct vb2_buffer *vb) new_params = (struct rkispp_params_cfg *)vb2_plane_vaddr(vb, 0); spin_lock_irqsave(¶ms_vdev->config_lock, flags); if (params_vdev->first_params) { - vb2_buffer_done(¶ms_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); params_vdev->first_params = false; - *params_vdev->cur_params = *new_params; if (new_params->module_init_ens) { if (params_vdev->dev->hw_dev->is_fec_ext) new_params->module_init_ens &= ~ISPP_MODULE_FEC_ST; stream_vdev->module_ens = new_params->module_init_ens; } - spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); wake_up(¶ms_vdev->dev->sync_onoff); - return; } spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); @@ -961,12 +914,10 @@ rkispp_params_init_vb2_queue(struct vb2_queue *q, return vb2_queue_init(q); } -void rkispp_params_isr(struct rkispp_params_vdev *params_vdev, u32 mis) +void rkispp_params_cfg(struct rkispp_params_vdev *params_vdev, u32 frame_id) { struct rkispp_params_cfg *new_params = NULL; - u32 module_en_update, module_cfg_update; - u32 module_ens, module_cur_ens; - bool isr_sync; + u32 module_en_update, module_cfg_update, module_ens; spin_lock(¶ms_vdev->config_lock); if (!params_vdev->streamon) { @@ -974,17 +925,30 @@ void rkispp_params_isr(struct rkispp_params_vdev *params_vdev, u32 mis) return; } - if (!params_vdev->cur_buf && - !list_empty(¶ms_vdev->params)) { + /* get buffer by frame_id */ + while (!list_empty(¶ms_vdev->params) && !params_vdev->cur_buf) { params_vdev->cur_buf = list_first_entry(¶ms_vdev->params, - struct rkispp_buffer, queue); - list_del(¶ms_vdev->cur_buf->queue); + struct rkispp_buffer, queue); + + new_params = (struct rkispp_params_cfg *)(params_vdev->cur_buf->vaddr[0]); + if (new_params->frame_id < frame_id) { + list_del(¶ms_vdev->cur_buf->queue); + vb2_buffer_done(¶ms_vdev->cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + params_vdev->cur_buf = NULL; + continue; + } else if (new_params->frame_id == frame_id) { + list_del(¶ms_vdev->cur_buf->queue); + } else { + params_vdev->cur_buf = NULL; + } + break; } if (!params_vdev->cur_buf) { spin_unlock(¶ms_vdev->config_lock); return; } + new_params = (struct rkispp_params_cfg *)(params_vdev->cur_buf->vaddr[0]); module_en_update = new_params->module_en_update; @@ -996,179 +960,48 @@ void rkispp_params_isr(struct rkispp_params_vdev *params_vdev, u32 mis) module_ens &= ~ISPP_MODULE_FEC; } - isr_sync = true; - if ((module_en_update & ISPP_MODULE_TNR) && - (module_ens & ISPP_MODULE_TNR) && - !is_tnr_enable(params_vdev)) - isr_sync = false; - if (module_cfg_update & ISPP_MODULE_TNR && - (mis & TNR_INT || !isr_sync)) { - tnr_config(params_vdev, - &new_params->tnr_cfg); - module_cfg_update &= ~ISPP_MODULE_TNR; - } - if (module_en_update & ISPP_MODULE_TNR && - (mis & TNR_INT || !isr_sync)) { - tnr_enable(params_vdev, - !!(module_ens & ISPP_MODULE_TNR)); - module_en_update &= ~ISPP_MODULE_TNR; - } - - isr_sync = true; - if ((module_en_update & ISPP_MODULE_NR) && - (module_ens & ISPP_MODULE_NR) && - !is_nr_enable(params_vdev)) - isr_sync = false; - if (module_cfg_update & ISPP_MODULE_NR && - (mis & NR_INT || !isr_sync)) { - nr_config(params_vdev, - &new_params->nr_cfg); - module_cfg_update &= ~ISPP_MODULE_NR; - } - if (module_en_update & ISPP_MODULE_NR && - (mis & NR_INT || !isr_sync)) { - nr_enable(params_vdev, - !!(module_ens & ISPP_MODULE_NR), - &new_params->nr_cfg); - module_en_update &= ~ISPP_MODULE_NR; - } - - isr_sync = true; - if ((module_en_update & ISPP_MODULE_SHP) && - (module_ens & ISPP_MODULE_SHP) && - !is_shp_enable(params_vdev)) - isr_sync = false; - if (module_cfg_update & ISPP_MODULE_SHP && - (mis & SHP_INT || !isr_sync)) { - shp_config(params_vdev, - &new_params->shp_cfg); - module_cfg_update &= ~ISPP_MODULE_SHP; - } - if (module_en_update & ISPP_MODULE_SHP && - (mis & SHP_INT || !isr_sync)) { - shp_enable(params_vdev, - !!(module_ens & ISPP_MODULE_SHP), - &new_params->shp_cfg); - module_en_update &= ~ISPP_MODULE_SHP; - } - - isr_sync = true; - if ((module_en_update & ISPP_MODULE_ORB) && - (module_ens & ISPP_MODULE_ORB) && - !is_orb_enable(params_vdev)) - isr_sync = false; - if (module_cfg_update & ISPP_MODULE_ORB && - (mis & ORB_INT || !isr_sync)) { - orb_config(params_vdev, - &new_params->orb_cfg); - module_cfg_update &= ~ISPP_MODULE_ORB; - } - if (module_en_update & ISPP_MODULE_ORB && - (mis & ORB_INT || !isr_sync)) { - orb_enable(params_vdev, - !!(module_ens & ISPP_MODULE_ORB)); - module_en_update &= ~ISPP_MODULE_ORB; - } - - isr_sync = true; - if ((module_en_update & ISPP_MODULE_FEC) && - (module_ens & ISPP_MODULE_FEC) && - !is_fec_enable(params_vdev)) - isr_sync = false; - if (module_cfg_update & ISPP_MODULE_FEC && - (mis & FEC_INT || !isr_sync)) { - fec_config(params_vdev, - &new_params->fec_cfg); - module_cfg_update &= ~ISPP_MODULE_FEC; - } - if (module_en_update & ISPP_MODULE_FEC && - (mis & FEC_INT || !isr_sync)) { - fec_enable(params_vdev, - !!(module_ens & ISPP_MODULE_FEC)); - module_en_update &= ~ISPP_MODULE_FEC; - } - - new_params->module_en_update = module_en_update; - new_params->module_cfg_update = module_cfg_update; - - module_cur_ens = 0; - if (is_tnr_enable(params_vdev)) - module_cur_ens |= ISPP_MODULE_TNR; - if (is_nr_enable(params_vdev)) - module_cur_ens |= ISPP_MODULE_NR; - if (is_shp_enable(params_vdev)) - module_cur_ens |= ISPP_MODULE_SHP; - if (is_orb_enable(params_vdev)) - module_cur_ens |= ISPP_MODULE_ORB; - if (is_fec_enable(params_vdev)) - module_cur_ens |= ISPP_MODULE_FEC; - - if (!(module_en_update & module_cur_ens) && - !(module_cfg_update & module_cur_ens)) { - vb2_buffer_done(¶ms_vdev->cur_buf->vb.vb2_buf, - VB2_BUF_STATE_DONE); - params_vdev->cur_buf = NULL; - } - spin_unlock(¶ms_vdev->config_lock); -} - -void rkispp_params_configure(struct rkispp_params_vdev *params_vdev) -{ - u32 module_en_update = params_vdev->cur_params->module_en_update; - u32 module_cfg_update = params_vdev->cur_params->module_cfg_update; - u32 module_ens = params_vdev->cur_params->module_ens; - unsigned long flags; - - if (params_vdev->dev->hw_dev->is_fec_ext) { - module_en_update &= ~ISPP_MODULE_FEC; - module_cfg_update &= ~ISPP_MODULE_FEC; - module_ens &= ~ISPP_MODULE_FEC; - } - - spin_lock_irqsave(¶ms_vdev->config_lock, flags); - if (params_vdev->first_params) { - params_vdev->first_params = false; - v4l2_warn(¶ms_vdev->dev->v4l2_dev, - "can not get first iq setting in stream on\n"); - } - spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); - if (module_cfg_update & ISPP_MODULE_TNR) tnr_config(params_vdev, - ¶ms_vdev->cur_params->tnr_cfg); + &new_params->tnr_cfg); if (module_en_update & ISPP_MODULE_TNR) tnr_enable(params_vdev, !!(module_ens & ISPP_MODULE_TNR)); if (module_cfg_update & ISPP_MODULE_NR) nr_config(params_vdev, - ¶ms_vdev->cur_params->nr_cfg); + &new_params->nr_cfg); if (module_en_update & ISPP_MODULE_NR) nr_enable(params_vdev, !!(module_ens & ISPP_MODULE_NR), - ¶ms_vdev->cur_params->nr_cfg); + &new_params->nr_cfg); if (module_cfg_update & ISPP_MODULE_SHP) shp_config(params_vdev, - ¶ms_vdev->cur_params->shp_cfg); + &new_params->shp_cfg); if (module_en_update & ISPP_MODULE_SHP) shp_enable(params_vdev, !!(module_ens & ISPP_MODULE_SHP), - ¶ms_vdev->cur_params->shp_cfg); + &new_params->shp_cfg); if (module_cfg_update & ISPP_MODULE_FEC) fec_config(params_vdev, - ¶ms_vdev->cur_params->fec_cfg); + &new_params->fec_cfg); if (module_en_update & ISPP_MODULE_FEC) fec_enable(params_vdev, !!(module_ens & ISPP_MODULE_FEC)); if (module_cfg_update & ISPP_MODULE_ORB) orb_config(params_vdev, - ¶ms_vdev->cur_params->orb_cfg); + &new_params->orb_cfg); if (module_en_update & ISPP_MODULE_ORB) orb_enable(params_vdev, !!(module_ens & ISPP_MODULE_ORB)); + + vb2_buffer_done(¶ms_vdev->cur_buf->vb.vb2_buf, + VB2_BUF_STATE_DONE); + params_vdev->cur_buf = NULL; + + spin_unlock(¶ms_vdev->config_lock); } void rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev *params_vdev, diff --git a/drivers/media/platform/rockchip/ispp/params.h b/drivers/media/platform/rockchip/ispp/params.h index 30c391b98065..d8ae3365dac5 100644 --- a/drivers/media/platform/rockchip/ispp/params.h +++ b/drivers/media/platform/rockchip/ispp/params.h @@ -33,8 +33,7 @@ struct rkispp_params_vdev { int rkispp_register_params_vdev(struct rkispp_device *dev); void rkispp_unregister_params_vdev(struct rkispp_device *dev); -void rkispp_params_configure(struct rkispp_params_vdev *params_vdev); -void rkispp_params_isr(struct rkispp_params_vdev *params_vdev, u32 mis); +void rkispp_params_cfg(struct rkispp_params_vdev *params_vdev, u32 frame_id); void rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev *params_vdev, struct rkispp_fecbuf_info *fecbuf); void rkispp_params_set_fecbuf_size(struct rkispp_params_vdev *params_vdev, diff --git a/drivers/media/platform/rockchip/ispp/stream.c b/drivers/media/platform/rockchip/ispp/stream.c index abcdb1e1dd40..c983df480023 100644 --- a/drivers/media/platform/rockchip/ispp/stream.c +++ b/drivers/media/platform/rockchip/ispp/stream.c @@ -1123,8 +1123,6 @@ static int config_modules(struct rkispp_device *dev) if (ret < 0) goto free_nr; - rkispp_params_configure(&dev->params_vdev); - return 0; free_nr: nr_free_buf(dev); @@ -2399,6 +2397,7 @@ static void fec_work_event(struct rkispp_device *dev, offset += size; reg_buf->reg_size = offset; } + writel(FEC_ST, base + RKISPP_CTRL_STRT); vdev->fec.is_end = false; } @@ -2578,6 +2577,7 @@ static void nr_work_event(struct rkispp_device *dev, } rkispp_update_regs(dev, RKISPP_NR, RKISPP_ORB_MAX_FEATURE); } + writel(OTHER_FORCE_UPD, base + RKISPP_CTRL_UPDATE); v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev, @@ -2637,6 +2637,7 @@ static void nr_work_event(struct rkispp_device *dev, offset += size; reg_buf->reg_size = offset; } + if (!is_quick) writel(NR_SHP_ST, base + RKISPP_CTRL_STRT); vdev->nr.is_end = false; @@ -2893,6 +2894,7 @@ static void tnr_work_event(struct rkispp_device *dev, offset += size; reg_buf->reg_size = offset; } + writel(TNR_ST, base + RKISPP_CTRL_STRT); vdev->tnr.is_end = false; } @@ -3101,7 +3103,6 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev) if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM) rkispp_clear_bits(dev, RKISPP_TNR_CTRL, SW_TNR_1ST_FRM); - rkispp_params_isr(&dev->params_vdev, mis_val); rkispp_stats_isr(&dev->stats_vdev, mis_val); for (i = 0; i <= STREAM_S2; i++) { diff --git a/include/uapi/linux/rkispp-config.h b/include/uapi/linux/rkispp-config.h index 1c4f3ab4fb46..5146cd60f224 100644 --- a/include/uapi/linux/rkispp-config.h +++ b/include/uapi/linux/rkispp-config.h @@ -335,6 +335,7 @@ struct rkispp_params_cfg { u32 module_cfg_update; u32 module_init_ens; + u32 frame_id; struct rkispp_tnr_config tnr_cfg; struct rkispp_nr_config nr_cfg; struct rkispp_sharp_config shp_cfg;