diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index e4d159d20e75..9d7b1d657920 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -304,7 +304,6 @@ static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq) params_vdev->first_cfg_params = true; return; } - rkisp_params_disable_isp(params_vdev); /* clean module params */ params_vdev->ops->clear_first_param(params_vdev); params_vdev->rdbk_times = 0; @@ -566,9 +565,12 @@ void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id void rkisp_params_stream_stop(struct rkisp_isp_params_vdev *params_vdev) { + rkisp_params_disable_isp(params_vdev); /* isp stop to free buf */ if (params_vdev->ops->stream_stop) params_vdev->ops->stream_stop(params_vdev); + if (!atomic_read(¶ms_vdev->open_cnt) && params_vdev->ops->fop_release) + params_vdev->ops->fop_release(params_vdev); } bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index 8c927f6be903..50d7631c2f39 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -5066,9 +5066,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, rkisp_free_buffer(params_vdev->dev, buf); } else { is_alloc = false; - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) + if (rkisp_buf_get_fd(ispdev, buf, false) < 0) goto err; + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; } } if (is_alloc) { @@ -5079,9 +5079,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, goto err; } mesh_head = (struct isp2x_mesh_head *)buf->vaddr; - mesh_head->stat = MESH_BUF_INIT; - mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); } + mesh_head->stat = MESH_BUF_INIT; + mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); buf++; } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v33.c b/drivers/media/platform/rockchip/isp/isp_params_v33.c index 626f85ce1ba5..c8207681a8ce 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v33.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v33.c @@ -4055,9 +4055,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, rkisp_free_buffer(params_vdev->dev, buf); } else { is_alloc = false; - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) + if (rkisp_buf_get_fd(ispdev, buf, false) < 0) goto err; + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; } } if (is_alloc) { @@ -4068,9 +4068,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, goto err; } mesh_head = (struct isp2x_mesh_head *)buf->vaddr; - mesh_head->stat = MESH_BUF_INIT; - mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); } + mesh_head->stat = MESH_BUF_INIT; + mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); buf++; } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.c b/drivers/media/platform/rockchip/isp/isp_params_v35.c index ab834ddc5d80..177b5f600f34 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v35.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.c @@ -4988,9 +4988,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, rkisp_free_buffer(params_vdev->dev, buf); } else { is_alloc = false; - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) + if (rkisp_buf_get_fd(ispdev, buf, false) < 0) goto err; + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; } } if (is_alloc) { @@ -5001,11 +5001,12 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, goto err; } mesh_head = (struct isp2x_mesh_head *)buf->vaddr; - mesh_head->stat = MESH_BUF_INIT; - mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); + } + mesh_head->stat = MESH_BUF_INIT; + mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); + if (meshsize->module_id == ISP35_MODULE_BAY3D) mesh_head->data1_oft = mesh_head->data_oft + ALIGN(priv->b3dldc_hsize * 4 * priv->b3dldch_vsize, 16); - } buf++; } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v39.c b/drivers/media/platform/rockchip/isp/isp_params_v39.c index e152770dd3fd..41fecc0794fc 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v39.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v39.c @@ -4430,9 +4430,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, rkisp_free_buffer(params_vdev->dev, buf); } else { is_alloc = false; - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) + if (rkisp_buf_get_fd(ispdev, buf, false) < 0) goto err; + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; } } if (is_alloc) { @@ -4443,9 +4443,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, goto err; } mesh_head = (struct isp2x_mesh_head *)buf->vaddr; - mesh_head->stat = MESH_BUF_INIT; - mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); } + mesh_head->stat = MESH_BUF_INIT; + mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); buf++; } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index a727ab68bee2..310a4a6d1aaa 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -4497,6 +4497,7 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, u32 mesh_size, buf_size; int i, ret, id = meshsize->unite_isp_id; int buf_cnt = meshsize->buf_cnt; + bool is_alloc; priv_val = params_vdev->priv_val; if (!priv_val) { @@ -4529,14 +4530,26 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, buf->is_need_vaddr = true; buf->is_need_dbuf = true; buf->is_need_dmafd = true; - buf->size = buf_size; - ret = rkisp_alloc_buffer(params_vdev->dev, buf); - if (ret) { - dev_err(dev, "%s failed\n", __func__); - goto err; + is_alloc = true; + if (buf->mem_priv) { + if (buf_size > buf->size) { + rkisp_free_buffer(params_vdev->dev, buf); + } else { + is_alloc = false; + if (rkisp_buf_get_fd(ispdev, buf, false) < 0) + goto err; + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; + } + } + if (is_alloc) { + buf->size = buf_size; + ret = rkisp_alloc_buffer(params_vdev->dev, buf); + if (ret) { + dev_err(dev, "%s failed\n", __func__); + goto err; + } + mesh_head = (struct isp2x_mesh_head *)buf->vaddr; } - - mesh_head = (struct isp2x_mesh_head *)buf->vaddr; mesh_head->stat = MESH_BUF_INIT; mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); buf++; diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index 170a3a4e0e60..cc75c0dcdcb3 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -219,6 +219,8 @@ static void rkisp_stats_vb2_stop_streaming(struct vb2_queue *vq) stats_vdev->ae_meas_done_next = false; stats_vdev->af_meas_done_next = false; + if (stats_vdev->ops->stats_stop) + stats_vdev->ops->stats_stop(stats_vdev); } static int diff --git a/drivers/media/platform/rockchip/isp/isp_stats.h b/drivers/media/platform/rockchip/isp/isp_stats.h index 962e8c073f8d..aea0e5d1ffa1 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.h +++ b/drivers/media/platform/rockchip/isp/isp_stats.h @@ -38,6 +38,7 @@ struct rkisp_isp_stats_ops { void (*first_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev); void (*next_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev); int (*stats_tb)(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_buffer *stats_buf); + void (*stats_stop)(struct rkisp_isp_stats_vdev *stats_vdev); }; /* diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/drivers/media/platform/rockchip/isp/isp_stats_v32.c index 9fe55848abbd..d411bac50e66 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.c @@ -1146,6 +1146,21 @@ rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_stats_update_buf(stats_vdev); } +static void rkisp_stats_stop_v32(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + u32 val, addr; + + /* aiq crash or exit first */ + if (dev->isp_state & ISP_START && + stats_vdev->stats_buf[0].mem_priv) { + rkisp_stats_update_buf(stats_vdev); + addr = stats_vdev->stats_buf[0].dma_addr; + readl_poll_timeout(dev->hw_dev->base_addr + ISP3X_MI_3A_WR_BASE, + val, val == addr, 5000, 50000); + } +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v32, .send_meas = rkisp_stats_send_meas_v32, @@ -1154,6 +1169,7 @@ static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .stats_tb = rkisp_stats_tb_v32, .first_ddr_cfg = rkisp_stats_first_ddr_config_v32, .next_ddr_cfg = rkisp_stats_next_ddr_config_v32, + .stats_stop = rkisp_stats_stop_v32, }; void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) @@ -1167,6 +1183,7 @@ void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_isp_stats_ops_tbl.stats_tb = NULL; rkisp_isp_stats_ops_tbl.first_ddr_cfg = NULL; rkisp_isp_stats_ops_tbl.next_ddr_cfg = NULL; + rkisp_isp_stats_ops_tbl.stats_stop = NULL; } stats_vdev->ops = &rkisp_isp_stats_ops_tbl; } diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v33.c b/drivers/media/platform/rockchip/isp/isp_stats_v33.c index 887f90f7d487..1c77c480c8f1 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v33.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v33.c @@ -568,6 +568,21 @@ rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_stats_update_buf(stats_vdev); } +static void rkisp_stats_stop_v33(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + u32 val, addr; + + /* aiq crash or exit first */ + if (dev->isp_state & ISP_START && + stats_vdev->stats_buf[0].mem_priv) { + rkisp_stats_update_buf(stats_vdev); + addr = stats_vdev->stats_buf[0].dma_addr; + readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD, + val, val == addr, 5000, 50000); + } +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v33, .send_meas = rkisp_stats_send_meas_v33, @@ -575,6 +590,7 @@ static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .stats_tb = rkisp_stats_tb_v33, .first_ddr_cfg = rkisp_stats_first_ddr_config_v33, .next_ddr_cfg = rkisp_stats_next_ddr_config_v33, + .stats_stop = rkisp_stats_stop_v33, }; void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v35.c b/drivers/media/platform/rockchip/isp/isp_stats_v35.c index d6cf5eb7c64c..6d53d32891a4 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v35.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v35.c @@ -862,12 +862,28 @@ rkisp_stats_next_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev) } } +static void rkisp_stats_stop_v35(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + u32 val, addr; + + /* aiq crash or exit first */ + if (dev->isp_state & ISP_START && + stats_vdev->stats_buf[0].mem_priv) { + rkisp_stats_update_buf(stats_vdev); + addr = stats_vdev->stats_buf[0].dma_addr; + readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD, + val, val == addr, 5000, 50000); + } +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v35, .get_stat_size = rkisp_get_stat_size_v35, .stats_tb = rkisp_stats_tb_v35, .first_ddr_cfg = rkisp_stats_first_ddr_config_v35, .next_ddr_cfg = rkisp_stats_next_ddr_config_v35, + .stats_stop = rkisp_stats_stop_v35, }; void rkisp_init_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v39.c b/drivers/media/platform/rockchip/isp/isp_stats_v39.c index 69672a06cb9b..48eb65ba12ad 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v39.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v39.c @@ -536,11 +536,27 @@ rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev) } } +static void rkisp_stats_stop_v39(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_device *dev = stats_vdev->dev; + u32 val, addr; + + /* aiq crash or exit first */ + if (dev->isp_state & ISP_START && + stats_vdev->stats_buf[0].mem_priv) { + rkisp_stats_update_buf(stats_vdev); + addr = stats_vdev->stats_buf[0].dma_addr; + readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD, + val, val == addr, 5000, 50000); + } +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v39, .get_stat_size = rkisp_get_stat_size_v39, .first_ddr_cfg = rkisp_stats_first_ddr_config_v39, .next_ddr_cfg = rkisp_stats_next_ddr_config_v39, + .stats_stop = rkisp_stats_stop_v39, }; void rkisp_init_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev)