diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index 80536de52a56..7a1607ebf453 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -192,6 +192,42 @@ void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) } } +int rkisp_buf_get_fd(struct rkisp_device *dev, + struct rkisp_dummy_buffer *buf, bool try_fd) +{ + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; + bool new_dbuf = false; + + if (!buf || !buf->mem_priv) + return -EINVAL; + if (try_fd && buf->is_need_dmafd) + return 0; + if (try_fd) { + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + } + + if (buf->is_need_dbuf && !buf->dbuf) { + buf->dbuf = g_ops->get_dmabuf(buf->mem_priv, O_RDWR); + new_dbuf = true; + } + + if (buf->is_need_dmafd) { + buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); + if (buf->dma_fd < 0) { + if (new_dbuf) { + dma_buf_put(buf->dbuf); + buf->dbuf = NULL; + buf->is_need_dbuf = false; + } + buf->is_need_dmafd = false; + return -EINVAL; + } + get_dma_buf(buf->dbuf); + } + return 0; +} + int rkisp_alloc_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf) { @@ -228,17 +264,13 @@ int rkisp_alloc_buffer(struct rkisp_device *dev, } if (buf->is_need_vaddr) buf->vaddr = g_ops->vaddr(mem_priv); - if (buf->is_need_dbuf) { - buf->dbuf = g_ops->get_dmabuf(mem_priv, O_RDWR); - if (buf->is_need_dmafd) { - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) { - dma_buf_put(buf->dbuf); - ret = buf->dma_fd; - goto err; - } - get_dma_buf(buf->dbuf); - } + ret = rkisp_buf_get_fd(dev, buf, false); + if (ret < 0) { + g_ops->put(buf->mem_priv); + buf->mem_priv = NULL; + buf->vaddr = NULL; + buf->size = 0; + goto err; } v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s buf:0x%x~0x%x size:%d\n", __func__, diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 7f6e41e699b6..8d4fd4649215 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -187,6 +187,7 @@ void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end); +int rkisp_buf_get_fd(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf, bool try_fd); int rkisp_alloc_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); void rkisp_free_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); void rkisp_prepare_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 03fd7fce0d7e..3c4379ef479b 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -487,6 +487,14 @@ int rkisp_params_info2ddr_cfg(struct rkisp_isp_params_vdev *params_vdev, return ret; } +void rkisp_params_get_bay3d_buffd(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + memset(bay3dbuf, -1, sizeof(*bay3dbuf)); + if (params_vdev->ops->get_bay3d_buffd) + params_vdev->ops->get_bay3d_buffd(params_vdev, bay3dbuf); +} + int rkisp_register_params_vdev(struct rkisp_isp_params_vdev *params_vdev, struct v4l2_device *v4l2_dev, struct rkisp_device *dev) diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index 2d58aba98d16..b6bbf1d7ec66 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -42,6 +42,8 @@ struct rkisp_isp_params_ops { void (*fop_release)(struct rkisp_isp_params_vdev *params_vdev); bool (*check_bigmode)(struct rkisp_isp_params_vdev *params_vdev); int (*info2ddr_cfg)(struct rkisp_isp_params_vdev *params_vdev, void *arg); + void (*get_bay3d_buffd)(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf); }; /* @@ -147,4 +149,6 @@ 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); bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev); int rkisp_params_info2ddr_cfg(struct rkisp_isp_params_vdev *params_vdev, void *arg); +void rkisp_params_get_bay3d_buffd(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf); #endif /* _RKISP_ISP_PARAM_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index e13e97ca53d0..c6f22d603754 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -3973,6 +3973,19 @@ end: return ispdev->is_bigmode = is_bigmode; } +static void +rkisp_params_get_bay3d_buffd_v21(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v21 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf = &priv_val->buf_3dnr; + + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; +} + /* Not called when the camera active, thus not isr protection. */ static void rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev) @@ -4330,6 +4343,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .stream_stop = rkisp_params_stream_stop_v2x, .fop_release = rkisp_params_fop_release_v2x, .check_bigmode = rkisp_params_check_bigmode_v21, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v21, }; int rkisp_init_params_vdev_v21(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 23072b4628de..ac46505c917d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -5209,9 +5209,9 @@ rkisp_params_info2ddr_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, void *a priv_val->buf_info_owner = cfg->owner; return 0; case RKISP_INFO2DRR_OWNER_GAIN: - ctrl = ISP3X_GAIN_2DDR_mode(cfg->u.gain.gain2ddr_mode); + ctrl = ISP3X_GAIN_2DDR_MODE(cfg->u.gain.gain2ddr_mode); ctrl |= ISP3X_GAIN_2DDR_EN; - mask = ISP3X_GAIN_2DDR_mode(3); + mask = ISP3X_GAIN_2DDR_MODE(3); reg = ISP3X_GAIN_CTRL; if (cfg->wsize) @@ -5296,6 +5296,26 @@ err: return -ENOMEM; } +static void +rkisp_params_get_bay3d_buffd_v32(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v32 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v32.ds_fd = buf->dma_fd; + bay3dbuf->u.v32.ds_size = buf->size; +} + static void rkisp_params_stream_stop_v32(struct rkisp_isp_params_vdev *params_vdev) { @@ -5529,6 +5549,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .fop_release = rkisp_params_fop_release_v32, .check_bigmode = rkisp_params_check_bigmode_v32, .info2ddr_cfg = rkisp_params_info2ddr_cfg_v32, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v32, }; int rkisp_init_params_vdev_v32(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 0491cc9bd8ba..96333d4e72a0 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -3526,26 +3526,26 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) return; if (en) { - if (!priv_val->buf_3dnr_iir[id].mem_priv) { + if (!priv_val->buf_3dnr_iir.mem_priv) { dev_err(ispdev->dev, "no bay3d buffer available\n"); return; } - value = priv_val->buf_3dnr_iir[id].size; + value = priv_val->buf_3dnr_iir.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); - value = priv_val->buf_3dnr_iir[id].dma_addr; + value = priv_val->buf_3dnr_iir.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); - value = priv_val->buf_3dnr_cur[id].size; + value = priv_val->buf_3dnr_cur.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); - value = priv_val->buf_3dnr_cur[id].dma_addr; + value = priv_val->buf_3dnr_cur.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); - value = priv_val->buf_3dnr_ds[id].size; + value = priv_val->buf_3dnr_ds.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); - value = priv_val->buf_3dnr_ds[id].dma_addr; + value = priv_val->buf_3dnr_ds.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_RD_BASE, id); @@ -4164,42 +4164,41 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, if (ispdev->hw_dev->unite) w = ALIGN(isp_sdev->in_crop.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); - for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { - size = ALIGN((w + w / 8) * h * 2, 16); + size = ALIGN((w + w / 8) * h * 2, 16); - priv_val->buf_3dnr_iir[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - if (ret) { - dev_err(ispdev->dev, "alloc bay3d iir buf fail:%d\n", ret); - goto err_3dnr; - } + if (ispdev->hw_dev->unite) + size *= 2; + priv_val->buf_3dnr_iir.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_iir); + if (ret) { + dev_err(ispdev->dev, "alloc bay3d iir buf fail:%d\n", ret); + goto err_3dnr; + } + priv_val->buf_3dnr_cur.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_cur); + if (ret) { + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + dev_err(ispdev->dev, "alloc bay3d cur buf fail:%d\n", ret); + goto err_3dnr; + } - priv_val->buf_3dnr_cur[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - if (ret) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - dev_err(ispdev->dev, "alloc bay3d cur buf fail:%d\n", ret); - goto err_3dnr; - } - - size = 2 * ALIGN(w * h / 64, 16); - priv_val->buf_3dnr_ds[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); - if (ret) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - dev_err(ispdev->dev, "alloc bay3d ds buf fail:%d\n", ret); - goto err_3dnr; - } + size = 2 * ALIGN(w * h / 64, 16); + if (ispdev->hw_dev->unite) + size *= 2; + priv_val->buf_3dnr_ds.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_ds); + if (ret) { + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + dev_err(ispdev->dev, "alloc bay3d ds buf fail:%d\n", ret); + goto err_3dnr; } } return 0; err_3dnr: - for (id -= 1; id >= 0; id--) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); - } + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); id = ispdev->hw_dev->unite ? 1 : 0; i = ISP3X_3DLUT_BUF_NUM; err_3dlut: @@ -4393,6 +4392,32 @@ end: return ispdev->is_bigmode = is_bigmode; } +static void +rkisp_params_get_bay3d_buffd_v3x(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v3x *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_cur; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v30.cur_fd = buf->dma_fd; + bay3dbuf->u.v30.cur_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v30.ds_fd = buf->dma_fd; + bay3dbuf->u.v30.ds_size = buf->size; +} + /* Not called when the camera active, thus not isr protection. */ static void rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) @@ -4615,10 +4640,10 @@ rkisp_params_stream_stop_v3x(struct rkisp_isp_params_vdev *params_vdev) priv_val = (struct rkisp_isp_params_val_v3x *)params_vdev->priv_val; tasklet_disable(&priv_val->lsc_tasklet); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); for (i = 0; i < ISP3X_3DLUT_BUF_NUM; i++) rkisp_free_buffer(ispdev, &priv_val->buf_3dlut[id][i]); } @@ -4859,6 +4884,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .stream_stop = rkisp_params_stream_stop_v3x, .fop_release = rkisp_params_fop_release_v3x, .check_bigmode = rkisp_params_check_bigmode_v3x, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v3x, }; int rkisp_init_params_vdev_v3x(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.h b/drivers/media/platform/rockchip/isp/isp_params_v3x.h index 0d5041ddf6f4..b7bc923521c8 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.h @@ -183,9 +183,9 @@ struct rkisp_isp_params_val_v3x { struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; u32 buf_cac_idx[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_iir[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_cur[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_ds[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dnr_iir; + struct rkisp_dummy_buffer buf_3dnr_cur; + struct rkisp_dummy_buffer buf_3dnr_ds; bool dhaz_en; bool drc_en; diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index cf2949d5e9db..223f674d99ea 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -1009,23 +1009,23 @@ static void rkisp_proc_dump_mem(struct rkisp_device *dev) if (dev->isp_ver == ISP_V30) { struct rkisp_isp_params_val_v3x *p = dev->params_vdev.priv_val; - if (p->buf_3dnr_iir[0].mem_priv) { - if (!p->buf_3dnr_iir[0].is_need_vaddr) - p->buf_3dnr_iir[0].vaddr = g_ops->vaddr(p->buf_3dnr_iir[0].mem_priv); - iir_addr = p->buf_3dnr_iir[0].vaddr; - iir_size = p->buf_3dnr_iir[0].size; + if (p->buf_3dnr_iir.mem_priv) { + if (!p->buf_3dnr_iir.is_need_vaddr) + p->buf_3dnr_iir.vaddr = g_ops->vaddr(p->buf_3dnr_iir.mem_priv); + iir_addr = p->buf_3dnr_iir.vaddr; + iir_size = p->buf_3dnr_iir.size; } - if (p->buf_3dnr_cur[0].mem_priv) { - if (!p->buf_3dnr_cur[0].is_need_vaddr) - p->buf_3dnr_cur[0].vaddr = g_ops->vaddr(p->buf_3dnr_cur[0].mem_priv); - cur_addr = p->buf_3dnr_cur[0].vaddr; - cur_size = p->buf_3dnr_cur[0].size; + if (p->buf_3dnr_cur.mem_priv) { + if (!p->buf_3dnr_cur.is_need_vaddr) + p->buf_3dnr_cur.vaddr = g_ops->vaddr(p->buf_3dnr_cur.mem_priv); + cur_addr = p->buf_3dnr_cur.vaddr; + cur_size = p->buf_3dnr_cur.size; } - if (p->buf_3dnr_ds[0].mem_priv) { - if (!p->buf_3dnr_ds[0].is_need_vaddr) - p->buf_3dnr_ds[0].vaddr = g_ops->vaddr(p->buf_3dnr_ds[0].mem_priv); - ds_addr = p->buf_3dnr_ds[0].vaddr; - ds_size = p->buf_3dnr_ds[0].size; + if (p->buf_3dnr_ds.mem_priv) { + if (!p->buf_3dnr_ds.is_need_vaddr) + p->buf_3dnr_ds.vaddr = g_ops->vaddr(p->buf_3dnr_ds.mem_priv); + ds_addr = p->buf_3dnr_ds.vaddr; + ds_size = p->buf_3dnr_ds.size; } } diff --git a/drivers/media/platform/rockchip/isp/regs_v3x.h b/drivers/media/platform/rockchip/isp/regs_v3x.h index 5e4c85710ee1..0fe2e47254dd 100644 --- a/drivers/media/platform/rockchip/isp/regs_v3x.h +++ b/drivers/media/platform/rockchip/isp/regs_v3x.h @@ -2230,7 +2230,7 @@ /* GAIN */ #define ISP3X_GAIN_2DDR_EN BIT(24) -#define ISP3X_GAIN_2DDR_mode(a) (((a) & 0x3) << 25) +#define ISP3X_GAIN_2DDR_MODE(a) (((a) & 0x3) << 25) /* DPCC */ #define ISP3X_DPCC_WORKING BIT(30) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index e09db6296f0f..18a4d871ba9c 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3623,6 +3623,9 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKISP_VICAP_CMD_MODE: ret = rkisp_set_work_mode_by_vicap(isp_dev, arg); break; + case RKISP_CMD_GET_BAY3D_BUFFD: + rkisp_params_get_bay3d_buffd(&isp_dev->params_vdev, arg); + break; default: ret = -ENOIOCTLCMD; } @@ -3635,103 +3638,91 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg) { void __user *up = compat_ptr(arg); - struct isp2x_csi_trigger trigger; - struct rkisp_thunderboot_resmem resmem; - struct rkisp_ldchbuf_info ldchbuf; - struct rkisp_ldchbuf_size ldchsize; - struct rkisp_meshbuf_info meshbuf; - struct rkisp_meshbuf_size meshsize; - struct rkisp_thunderboot_shmem shmem; - struct isp2x_buf_idxfd idxfd; - struct rkisp_info2ddr info2ddr; + void *pbuf = NULL; long ret = 0; - u64 module_id; + u32 size = 0; + bool cp_t_us = false, cp_f_us = false; - if (!up && cmd != RKISP_CMD_FREE_SHARED_BUF) + if (!up && + cmd != RKISP_CMD_FREE_SHARED_BUF && + cmd != RKISP_CMD_MULTI_DEV_FORCE_ENUM) return -EINVAL; switch (cmd) { case RKISP_CMD_TRIGGER_READ_BACK: - if (copy_from_user(&trigger, up, sizeof(trigger))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &trigger); + size = sizeof(struct isp2x_csi_trigger); + cp_f_us = true; break; case RKISP_CMD_GET_SHARED_BUF: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - ret = rkisp_ioctl(sd, cmd, &resmem); - if (!ret && copy_to_user(up, &resmem, sizeof(resmem))) - ret = -EFAULT; + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + size = sizeof(struct rkisp_thunderboot_resmem); + cp_t_us = true; break; case RKISP_CMD_FREE_SHARED_BUF: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - ret = rkisp_ioctl(sd, cmd, NULL); + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: break; case RKISP_CMD_GET_LDCHBUF_INFO: - ret = rkisp_ioctl(sd, cmd, &ldchbuf); - if (!ret && copy_to_user(up, &ldchbuf, sizeof(ldchbuf))) - ret = -EFAULT; + size = sizeof(struct rkisp_ldchbuf_info); + cp_t_us = true; break; case RKISP_CMD_SET_LDCHBUF_SIZE: - if (copy_from_user(&ldchsize, up, sizeof(ldchsize))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &ldchsize); + size = sizeof(struct rkisp_ldchbuf_size); + cp_f_us = true; break; case RKISP_CMD_GET_MESHBUF_INFO: - if (copy_from_user(&meshbuf, up, sizeof(meshbuf))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &meshbuf); - if (!ret && copy_to_user(up, &meshbuf, sizeof(meshbuf))) - ret = -EFAULT; + size = sizeof(struct rkisp_meshbuf_info); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_SET_MESHBUF_SIZE: - if (copy_from_user(&meshsize, up, sizeof(meshsize))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &meshsize); + size = sizeof(struct rkisp_meshbuf_size); + cp_f_us = true; break; case RKISP_CMD_GET_SHM_BUFFD: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - if (copy_from_user(&shmem, up, sizeof(shmem))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &shmem); - if (!ret && copy_to_user(up, &shmem, sizeof(shmem))) - ret = -EFAULT; + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + size = sizeof(struct rkisp_thunderboot_shmem); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_GET_FBCBUF_FD: - ret = rkisp_ioctl(sd, cmd, &idxfd); - if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) - ret = -EFAULT; + size = sizeof(struct isp2x_buf_idxfd); + cp_t_us = true; break; case RKISP_CMD_INFO2DDR: - if (copy_from_user(&info2ddr, up, sizeof(info2ddr))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &info2ddr); - if (!ret && copy_to_user(up, &info2ddr, sizeof(info2ddr))) - ret = -EFAULT; + size = sizeof(struct rkisp_info2ddr); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_MESHBUF_FREE: - if (copy_from_user(&module_id, up, sizeof(module_id))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &module_id); + size = sizeof(u64); + cp_f_us = true; break; - case RKISP_CMD_MULTI_DEV_FORCE_ENUM: - ret = rkisp_ioctl(sd, cmd, NULL); - break; - case RKISP_VICAP_CMD_SET_STREAM: - ret = rkisp_ioctl(sd, cmd, NULL); + case RKISP_CMD_GET_BAY3D_BUFFD: + size = sizeof(struct rkisp_bay3dbuf_info); + cp_t_us = true; break; default: - ret = -ENOIOCTLCMD; + return -ENOIOCTLCMD; } + if (size) { + pbuf = kmalloc(size, GFP_KERNEL); + if (!pbuf) + return -ENOMEM; + } + if (cp_f_us && copy_from_user(pbuf, up, size)) { + ret = -EFAULT; + goto free_buf; + } + ret = rkisp_ioctl(sd, cmd, pbuf); + if (!ret && cp_t_us && copy_to_user(up, pbuf, size)) + ret = -EFAULT; +free_buf: + kfree(pbuf); return ret; } #endif diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index fc5177820177..7ea04e6f9477 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -58,6 +58,9 @@ #define RKISP_CMD_MULTI_DEV_FORCE_ENUM \ _IO('V', BASE_VIDIOC_PRIVATE + 13) +#define RKISP_CMD_GET_BAY3D_BUFFD \ + _IOR('V', BASE_VIDIOC_PRIVATE + 15, struct rkisp_bay3dbuf_info) + /****************ISP VIDEO IOCTL******************************/ #define RKISP_CMD_GET_CSI_MEMORY_MODE \ @@ -318,6 +321,23 @@ struct isp2x_mesh_head { __u32 data_oft; } __attribute__ ((packed)); +struct rkisp_bay3dbuf_info { + int iir_fd; + int iir_size; + union { + struct { + int cur_fd; + int cur_size; + int ds_fd; + int ds_size; + } v30; + struct { + int ds_fd; + int ds_size; + } v32; + } u; +} __attribute__ ((packed)); + #define RKISP_CMSK_WIN_MAX 12 #define RKISP_CMSK_WIN_MAX_V30 8 #define RKISP_CMSK_MOSAIC_MODE 0