diff --git a/drivers/media/platform/rockchip/ispp/common.c b/drivers/media/platform/rockchip/ispp/common.c index 91bd4cb96840..8e4b10508083 100644 --- a/drivers/media/platform/rockchip/ispp/common.c +++ b/drivers/media/platform/rockchip/ispp/common.c @@ -372,7 +372,6 @@ static void rkispp_queue_dmabuf(struct rkispp_hw_dev *hw, struct rkisp_ispp_buf vdev = &ispp->stream_vdev; val = (vdev->module_ens & ISPP_MODULE_TNR) ? ISPP_MODULE_TNR : ((vdev->module_ens & ISPP_MODULE_NR) ? ISPP_MODULE_NR : ISPP_MODULE_FEC); - ispp->params_vdev.params_ops->rkispp_params_cfg(&ispp->params_vdev, buf->frame_id); vdev->stream_ops->rkispp_module_work_event(ispp, buf, NULL, val, false); } diff --git a/drivers/media/platform/rockchip/ispp/dev.c b/drivers/media/platform/rockchip/ispp/dev.c index 5c9eb9ab5d27..a58bf3b7ea79 100644 --- a/drivers/media/platform/rockchip/ispp/dev.c +++ b/drivers/media/platform/rockchip/ispp/dev.c @@ -138,16 +138,29 @@ static int rkispp_create_links(struct rkispp_device *ispp_dev) /* params links */ flags = MEDIA_LNK_FL_ENABLED; - source = &ispp_dev->params_vdev.vnode.vdev.entity; + source = &ispp_dev->params_vdev[PARAM_VDEV_FEC].vnode.vdev.entity; ret = media_create_pad_link(source, 0, sink, RKISPP_PAD_SINK_PARAMS, flags); if (ret < 0) return ret; ispp_dev->stream_vdev.module_ens = ISPP_MODULE_FEC; if (ispp_dev->ispp_ver == ISPP_V10) { + /* params links */ + source = &ispp_dev->params_vdev[PARAM_VDEV_TNR].vnode.vdev.entity; + ret = media_create_pad_link(source, 0, sink, RKISPP_PAD_SINK_PARAMS, flags); + if (ret < 0) + return ret; + source = &ispp_dev->params_vdev[PARAM_VDEV_NR].vnode.vdev.entity; + ret = media_create_pad_link(source, 0, sink, RKISPP_PAD_SINK_PARAMS, flags); + if (ret < 0) + return ret; + /* stats links */ - flags = MEDIA_LNK_FL_ENABLED; source = &ispp_dev->ispp_sdev.sd.entity; - sink = &ispp_dev->stats_vdev.vnode.vdev.entity; + sink = &ispp_dev->stats_vdev[STATS_VDEV_TNR].vnode.vdev.entity; + ret = media_create_pad_link(source, RKISPP_PAD_SOURCE_STATS, sink, 0, flags); + if (ret < 0) + return ret; + sink = &ispp_dev->stats_vdev[STATS_VDEV_NR].vnode.vdev.entity; ret = media_create_pad_link(source, RKISPP_PAD_SOURCE_STATS, sink, 0, flags); if (ret < 0) return ret; @@ -193,7 +206,6 @@ static int rkispp_create_links(struct rkispp_device *ispp_dev) if (ret < 0) return ret; - /* default enable */ return 0; } @@ -205,11 +217,11 @@ static int rkispp_register_platform_subdevs(struct rkispp_device *ispp_dev) if (ret < 0) return ret; - ret = rkispp_register_params_vdev(ispp_dev); + ret = rkispp_register_params_vdevs(ispp_dev); if (ret < 0) goto err_unreg_stream_vdevs; - ret = rkispp_register_stats_vdev(ispp_dev); + ret = rkispp_register_stats_vdevs(ispp_dev); if (ret < 0) goto err_unreg_params_vdev; @@ -224,9 +236,9 @@ static int rkispp_register_platform_subdevs(struct rkispp_device *ispp_dev) err_unreg_ispp_subdev: rkispp_unregister_subdev(ispp_dev); err_unreg_stats_vdev: - rkispp_unregister_stats_vdev(ispp_dev); + rkispp_unregister_stats_vdevs(ispp_dev); err_unreg_params_vdev: - rkispp_unregister_params_vdev(ispp_dev); + rkispp_unregister_params_vdevs(ispp_dev); err_unreg_stream_vdevs: rkispp_unregister_stream_vdevs(ispp_dev); return ret; @@ -325,8 +337,8 @@ static int rkispp_plat_remove(struct platform_device *pdev) rkispp_proc_cleanup(ispp_dev); rkispp_unregister_subdev(ispp_dev); - rkispp_unregister_stats_vdev(ispp_dev); - rkispp_unregister_params_vdev(ispp_dev); + rkispp_unregister_stats_vdevs(ispp_dev); + rkispp_unregister_params_vdevs(ispp_dev); rkispp_unregister_stream_vdevs(ispp_dev); media_device_unregister(&ispp_dev->media_dev); diff --git a/drivers/media/platform/rockchip/ispp/dev.h b/drivers/media/platform/rockchip/ispp/dev.h index 32a6736bbb1c..065ce848435e 100644 --- a/drivers/media/platform/rockchip/ispp/dev.h +++ b/drivers/media/platform/rockchip/ispp/dev.h @@ -36,8 +36,8 @@ struct rkispp_device { struct rkispp_hw_dev *hw_dev; struct rkispp_subdev ispp_sdev; struct rkispp_stream_vdev stream_vdev; - struct rkispp_params_vdev params_vdev; - struct rkispp_stats_vdev stats_vdev; + struct rkispp_params_vdev params_vdev[PARAM_VDEV_MAX]; + struct rkispp_stats_vdev stats_vdev[STATS_VDEV_MAX]; struct proc_dir_entry *procfs; struct work_struct irq_work; diff --git a/drivers/media/platform/rockchip/ispp/hw.c b/drivers/media/platform/rockchip/ispp/hw.c index 9e0fae8f92e4..d1a5a01323d5 100644 --- a/drivers/media/platform/rockchip/ispp/hw.c +++ b/drivers/media/platform/rockchip/ispp/hw.c @@ -392,6 +392,9 @@ static int rkispp_hw_probe(struct platform_device *pdev) INIT_LIST_HEAD(&hw_dev->list); hw_dev->is_idle = true; hw_dev->is_single = true; + /* for frame end reset and config reg */ + if (hw_dev->ispp_ver == ISPP_V10) + hw_dev->is_single = false; hw_dev->is_fec_ext = false; hw_dev->is_dma_contig = true; hw_dev->is_dma_sg_ops = true; diff --git a/drivers/media/platform/rockchip/ispp/ispp.c b/drivers/media/platform/rockchip/ispp/ispp.c index e1efba145533..8ff615083995 100644 --- a/drivers/media/platform/rockchip/ispp/ispp.c +++ b/drivers/media/platform/rockchip/ispp/ispp.c @@ -408,13 +408,18 @@ static long rkispp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return -EINVAL; switch (cmd) { + case RKISPP_CMD_SET_INIT_MODULE: + ispp_dev->stream_vdev.module_ens = *((int *)arg); + if (ispp_dev->hw_dev->is_fec_ext) + ispp_dev->stream_vdev.module_ens &= ~ISPP_MODULE_FEC_ST; + break; case RKISPP_CMD_GET_FECBUF_INFO: fecbuf = (struct rkispp_fecbuf_info *)arg; - rkispp_params_get_fecbuf_inf(&ispp_dev->params_vdev, fecbuf); + rkispp_params_get_fecbuf_inf(&ispp_dev->params_vdev[PARAM_VDEV_FEC], fecbuf); break; case RKISPP_CMD_SET_FECBUF_SIZE: fecsize = (struct rkispp_fecbuf_size *)arg; - rkispp_params_set_fecbuf_size(&ispp_dev->params_vdev, fecsize); + rkispp_params_set_fecbuf_size(&ispp_dev->params_vdev[PARAM_VDEV_FEC], fecsize); break; case RKISP_ISPP_CMD_REQUEST_REGBUF: reg_buf = (struct rkisp_ispp_reg **)arg; @@ -425,9 +430,6 @@ static long rkispp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) *rkispp_reg_withstream = rkispp_is_reg_withstream_global(); break; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISPP_VERSION_V10) - case RKISPP_CMD_TRIGGER_YNRRUN: - rkispp_sendbuf_to_nr(ispp_dev, (struct rkispp_tnr_inf *)arg); - break; case RKISPP_CMD_GET_TNRBUF_FD: ret = rkispp_get_tnrbuf_fd(ispp_dev, (struct rkispp_buf_idxfd *)arg); break; @@ -449,7 +451,6 @@ static long rkispp_compat_ioctl32(struct v4l2_subdev *sd, void __user *up = compat_ptr(arg); struct rkispp_fecbuf_info fecbuf; struct rkispp_fecbuf_size fecsize; - struct rkispp_tnr_inf tnr_inf; struct rkispp_buf_idxfd idxfd; struct rkispp_trigger_mode t_mode; long ret = 0; @@ -468,11 +469,6 @@ static long rkispp_compat_ioctl32(struct v4l2_subdev *sd, return -EFAULT; ret = rkispp_ioctl(sd, cmd, &fecsize); break; - case RKISPP_CMD_TRIGGER_YNRRUN: - if (copy_from_user(&tnr_inf, up, sizeof(tnr_inf))) - return -EFAULT; - ret = rkispp_ioctl(sd, cmd, &tnr_inf); - break; case RKISPP_CMD_GET_TNRBUF_FD: ret = rkispp_ioctl(sd, cmd, &idxfd); if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) diff --git a/drivers/media/platform/rockchip/ispp/params.c b/drivers/media/platform/rockchip/ispp/params.c index 9d82b959b3c9..eba2b96167f2 100644 --- a/drivers/media/platform/rockchip/ispp/params.c +++ b/drivers/media/platform/rockchip/ispp/params.c @@ -187,10 +187,22 @@ static int rkispp_params_vb2_queue_setup(struct vb2_queue *vq, RKISP1_ISP_PARAMS_REQ_BUFS_MAX); *num_planes = 1; - if (dev->ispp_ver == ISPP_V10) - sizes[0] = sizeof(struct rkispp_params_cfg); - else if (dev->ispp_ver == ISPP_V20) + if (dev->ispp_ver == ISPP_V10) { + switch (params_vdev->vdev_id) { + case PARAM_VDEV_TNR: + sizes[0] = sizeof(struct rkispp_params_tnrcfg); + break; + case PARAM_VDEV_NR: + sizes[0] = sizeof(struct rkispp_params_nrcfg); + break; + case PARAM_VDEV_FEC: + default: + sizes[0] = sizeof(struct rkispp_params_feccfg); + break; + } + } else if (dev->ispp_ver == ISPP_V20) { sizes[0] = sizeof(struct fec_params_cfg); + } INIT_LIST_HEAD(¶ms_vdev->params); params_vdev->first_params = true; @@ -243,10 +255,6 @@ static void rkispp_params_vb2_stop_streaming(struct vb2_queue *vq) VB2_BUF_STATE_ERROR); params_vdev->cur_buf = NULL; } - - /* clean module params */ - params_vdev->cur_params->module_cfg_update = 0; - params_vdev->cur_params->module_en_update = 0; } static int @@ -309,7 +317,6 @@ static struct vb2_ops rkispp_params_vb2_ops = { .buf_queue = rkispp_params_vb2_buf_queue, .start_streaming = rkispp_params_vb2_start_streaming, .stop_streaming = rkispp_params_vb2_stop_streaming, - }; struct v4l2_file_operations rkispp_params_fops = { @@ -342,6 +349,9 @@ void rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev *params_vdev, { int i; + if (params_vdev->vdev_id != PARAM_VDEV_FEC) + return; + for (i = 0; i < FEC_MESH_BUF_NUM; i++) { fecbuf->buf_fd[i] = params_vdev->buf_fec[i].dma_fd; fecbuf->buf_size[i] = params_vdev->buf_fec[i].size; @@ -351,31 +361,42 @@ void rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev *params_vdev, void rkispp_params_set_fecbuf_size(struct rkispp_params_vdev *params_vdev, struct rkispp_fecbuf_size *fecsize) { + if (params_vdev->vdev_id != PARAM_VDEV_FEC) + return; + rkispp_param_deinit_fecbuf(params_vdev); rkispp_param_init_fecbuf(params_vdev, fecsize); } -int rkispp_register_params_vdev(struct rkispp_device *dev) +static int rkispp_register_params_vdev(struct rkispp_device *dev, + enum rkispp_paramvdev_id vdev_id) { - struct rkispp_params_vdev *params_vdev = &dev->params_vdev; + struct rkispp_params_vdev *params_vdev = &dev->params_vdev[vdev_id]; struct rkispp_vdev_node *node = ¶ms_vdev->vnode; struct video_device *vdev = &node->vdev; int ret; params_vdev->dev = dev; params_vdev->is_subs_evt = false; - params_vdev->cur_params = vmalloc(sizeof(*params_vdev->cur_params)); - if (!params_vdev->cur_params) - return -ENOMEM; + params_vdev->vdev_id = vdev_id; - params_vdev->cur_params->module_cfg_update = 0; - params_vdev->cur_params->module_en_update = 0; if (dev->ispp_ver == ISPP_V10) rkispp_params_init_ops_v10(params_vdev); if (dev->ispp_ver == ISPP_V20) rkispp_params_init_ops_v20(params_vdev); spin_lock_init(¶ms_vdev->config_lock); - strlcpy(vdev->name, "rkispp_input_params", sizeof(vdev->name)); + switch (vdev_id) { + case PARAM_VDEV_TNR: + strncpy(vdev->name, "rkispp_tnr_params", sizeof(vdev->name) - 1); + break; + case PARAM_VDEV_NR: + strncpy(vdev->name, "rkispp_nr_params", sizeof(vdev->name) - 1); + break; + case PARAM_VDEV_FEC: + default: + strncpy(vdev->name, "rkispp_fec_params", sizeof(vdev->name) - 1); + break; + } video_set_drvdata(vdev, params_vdev); vdev->ioctl_ops = &rkispp_params_ioctl; @@ -414,14 +435,49 @@ err_release_queue: return ret; } -void rkispp_unregister_params_vdev(struct rkispp_device *dev) +static void rkispp_unregister_params_vdev(struct rkispp_device *dev, + enum rkispp_paramvdev_id vdev_id) { - struct rkispp_params_vdev *params_vdev = &dev->params_vdev; + struct rkispp_params_vdev *params_vdev = &dev->params_vdev[vdev_id]; struct rkispp_vdev_node *node = ¶ms_vdev->vnode; struct video_device *vdev = &node->vdev; video_unregister_device(vdev); media_entity_cleanup(&vdev->entity); vb2_queue_release(vdev->queue); - vfree(params_vdev->cur_params); +} + +int rkispp_register_params_vdevs(struct rkispp_device *dev) +{ + int ret = 0; + + ret = rkispp_register_params_vdev(dev, PARAM_VDEV_FEC); + if (ret) + return ret; + + if (dev->ispp_ver == ISPP_V10) { + ret = rkispp_register_params_vdev(dev, PARAM_VDEV_TNR); + if (ret) { + rkispp_unregister_params_vdev(dev, PARAM_VDEV_FEC); + return ret; + } + + ret = rkispp_register_params_vdev(dev, PARAM_VDEV_NR); + if (ret) { + rkispp_unregister_params_vdev(dev, PARAM_VDEV_FEC); + rkispp_unregister_params_vdev(dev, PARAM_VDEV_TNR); + return ret; + } + } + + return ret; +} + +void rkispp_unregister_params_vdevs(struct rkispp_device *dev) +{ + rkispp_unregister_params_vdev(dev, PARAM_VDEV_FEC); + if (dev->ispp_ver == ISPP_V10) { + rkispp_unregister_params_vdev(dev, PARAM_VDEV_TNR); + rkispp_unregister_params_vdev(dev, PARAM_VDEV_NR); + } } diff --git a/drivers/media/platform/rockchip/ispp/params.h b/drivers/media/platform/rockchip/ispp/params.h index a5083891ac1f..c3011cca27fe 100644 --- a/drivers/media/platform/rockchip/ispp/params.h +++ b/drivers/media/platform/rockchip/ispp/params.h @@ -8,13 +8,13 @@ #include #include "common.h" -/* rkispp parameters device - * config_lock: lock to protect config - * params: queued buffer list - * cur_params: ispp params config - * cur_params: current buf of parameters - * first_params: the first params should take effect immediately - */ +enum rkispp_paramvdev_id { + PARAM_VDEV_TNR = 0, + PARAM_VDEV_NR, + PARAM_VDEV_FEC, + PARAM_VDEV_MAX +}; + #define ISPP_PACK_4BYTE(a, b, c, d) \ (((a) & 0xFF) << 0 | ((b) & 0xFF) << 8 | \ ((c) & 0xFF) << 16 | ((d) & 0xFF) << 24) @@ -34,6 +34,12 @@ #define ISPP_NOBIG_OVERFLOW_SIZE (2560 * 1440) +/* rkispp parameters device + * config_lock: lock to protect config + * params: queued buffer list + * cur_buf: current buf of parameters + * first_params: the first params should take effect immediately + */ struct rkispp_params_vdev { struct rkispp_vdev_node vnode; struct rkispp_device *dev; @@ -41,8 +47,6 @@ struct rkispp_params_vdev { spinlock_t config_lock; struct list_head params; - struct rkispp_params_cfg *cur_params; - struct fec_params_cfg *fec_params; struct rkispp_buffer *cur_buf; struct v4l2_format vdev_fmt; @@ -52,6 +56,8 @@ struct rkispp_params_vdev { struct rkispp_dummy_buffer buf_fec[FEC_MESH_BUF_NUM]; u32 buf_fec_idx; + + enum rkispp_paramvdev_id vdev_id; }; struct rkispp_params_ops { @@ -59,8 +65,8 @@ struct rkispp_params_ops { void (*rkispp_params_vb2_buf_queue)(struct vb2_buffer *vb); }; -int rkispp_register_params_vdev(struct rkispp_device *dev); -void rkispp_unregister_params_vdev(struct rkispp_device *dev); +int rkispp_register_params_vdevs(struct rkispp_device *dev); +void rkispp_unregister_params_vdevs(struct rkispp_device *dev); 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/params_v10.c b/drivers/media/platform/rockchip/ispp/params_v10.c index 9430d0b84797..dc2fc0d3f70d 100644 --- a/drivers/media/platform/rockchip/ispp/params_v10.c +++ b/drivers/media/platform/rockchip/ispp/params_v10.c @@ -20,7 +20,6 @@ static inline size_t get_input_size(struct rkispp_params_vdev *params_vdev) return isp_sdev->out_fmt.width * isp_sdev->out_fmt.height; } - static void tnr_config(struct rkispp_params_vdev *params_vdev, struct rkispp_tnr_config *arg) { @@ -558,22 +557,6 @@ static void fec_config(struct rkispp_params_vdev *params_vdev, rkispp_write(params_vdev->dev, RKISPP_FEC_CROP, val); } -static void fec_data_abandon(struct rkispp_params_vdev *vdev, - struct rkispp_params_cfg *params) -{ - struct rkispp_fec_head *data; - int i; - - for (i = 0; i < FEC_MESH_BUF_NUM; i++) { - if (params->fec_cfg.buf_fd == vdev->buf_fec[i].dma_fd) { - data = (struct rkispp_fec_head *)vdev->buf_fec[i].vaddr; - if (data) - data->stat = FEC_BUF_INIT; - break; - } - } -} - static void fec_enable(struct rkispp_params_vdev *params_vdev, bool en) { struct rkispp_device *dev = params_vdev->dev; @@ -604,9 +587,71 @@ 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 void params_vb2_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rkispp_buffer *params_buf = to_rkispp_buffer(vbuf); + struct vb2_queue *vq = vb->vb2_queue; + struct rkispp_params_vdev *params_vdev = vq->drv_priv; + struct rkispp_device *dev = params_vdev->dev; + struct rkispp_stream_vdev *vdev = &dev->stream_vdev; + void *buf_rd = NULL; + unsigned long flags; + u32 module; + + spin_lock_irqsave(¶ms_vdev->config_lock, flags); + if (params_vdev->first_params) { + params_vdev->first_params = false; + if (params_vdev->vdev_id == PARAM_VDEV_NR) + wake_up(¶ms_vdev->dev->sync_onoff); + } + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); + + params_buf->vaddr[0] = vb2_plane_vaddr(vb, 0); + spin_lock_irqsave(¶ms_vdev->config_lock, flags); + list_add_tail(¶ms_buf->queue, ¶ms_vdev->params); + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); + + switch (params_vdev->vdev_id) { + case PARAM_VDEV_TNR: + module = ISPP_MODULE_TNR; + break; + case PARAM_VDEV_NR: + module = ISPP_MODULE_NR; + spin_lock_irqsave(&vdev->tnr.buf_lock, flags); + if (!list_empty(&vdev->tnr.list_rpt)) { + buf_rd = list_first_entry(&vdev->tnr.list_rpt, + struct rkisp_ispp_buf, list); + list_del(&((struct rkisp_ispp_buf *)buf_rd)->list); + } + spin_unlock_irqrestore(&vdev->tnr.buf_lock, flags); + break; + case PARAM_VDEV_FEC: + default: + module = ISPP_MODULE_FEC; + } + vdev->stream_ops->rkispp_module_work_event(dev, buf_rd, NULL, module, false); +} + +static void fec_data_abandon(struct rkispp_params_vdev *vdev, + struct rkispp_params_feccfg *params) +{ + struct rkispp_fec_head *data; + int i; + + for (i = 0; i < FEC_MESH_BUF_NUM; i++) { + if (params->fec_cfg.buf_fd == vdev->buf_fec[i].dma_fd) { + data = (struct rkispp_fec_head *)vdev->buf_fec[i].vaddr; + if (data) + data->stat = FEC_BUF_INIT; + break; + } + } +} + static void rkispp_params_cfg(struct rkispp_params_vdev *params_vdev, u32 frame_id) { - struct rkispp_params_cfg *new_params = NULL; + struct rkispp_params_cfghead *param_head = NULL; u32 module_en_update, module_cfg_update, module_ens; spin_lock(¶ms_vdev->config_lock); @@ -620,15 +665,18 @@ static void rkispp_params_cfg(struct rkispp_params_vdev *params_vdev, u32 frame_ params_vdev->cur_buf = list_first_entry(¶ms_vdev->params, struct rkispp_buffer, queue); - new_params = (struct rkispp_params_cfg *)(params_vdev->cur_buf->vaddr[0]); - if (new_params->frame_id < frame_id) { - if (new_params->module_cfg_update & ISPP_MODULE_FEC) - fec_data_abandon(params_vdev, new_params); + param_head = (struct rkispp_params_cfghead *)(params_vdev->cur_buf->vaddr[0]); + if (param_head->frame_id < frame_id) { list_del(¶ms_vdev->cur_buf->queue); + /* force to on/off module */ + if (param_head->module_en_update) + break; + if (param_head->module_cfg_update & ISPP_MODULE_FEC) + fec_data_abandon(params_vdev, (struct rkispp_params_feccfg *)param_head); 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) { + } else if (param_head->frame_id == frame_id) { list_del(¶ms_vdev->cur_buf->queue); } else { params_vdev->cur_buf = NULL; @@ -641,53 +689,64 @@ static void rkispp_params_cfg(struct rkispp_params_vdev *params_vdev, u32 frame_ return; } - new_params = (struct rkispp_params_cfg *)(params_vdev->cur_buf->vaddr[0]); + param_head = (struct rkispp_params_cfghead *)(params_vdev->cur_buf->vaddr[0]); - module_en_update = new_params->module_en_update; - module_cfg_update = new_params->module_cfg_update; - module_ens = new_params->module_ens; + module_en_update = param_head->module_en_update; + module_cfg_update = param_head->module_cfg_update; + module_ens = param_head->module_ens; 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; } - if (module_cfg_update & ISPP_MODULE_TNR) - tnr_config(params_vdev, - &new_params->tnr_cfg); - if (module_en_update & ISPP_MODULE_TNR) - tnr_enable(params_vdev, - !!(module_ens & ISPP_MODULE_TNR)); + if (params_vdev->vdev_id == PARAM_VDEV_TNR) { + struct rkispp_params_tnrcfg *tnr_params; - if (module_cfg_update & ISPP_MODULE_NR) - nr_config(params_vdev, - &new_params->nr_cfg); - if (module_en_update & ISPP_MODULE_NR) - nr_enable(params_vdev, - !!(module_ens & ISPP_MODULE_NR), - &new_params->nr_cfg); + tnr_params = (struct rkispp_params_tnrcfg *)param_head; + if (module_cfg_update & ISPP_MODULE_TNR) + tnr_config(params_vdev, + &tnr_params->tnr_cfg); + if (module_en_update & ISPP_MODULE_TNR) + tnr_enable(params_vdev, + !!(module_ens & ISPP_MODULE_TNR)); + } else if (params_vdev->vdev_id == PARAM_VDEV_NR) { + struct rkispp_params_nrcfg *nr_params; - if (module_cfg_update & ISPP_MODULE_SHP) - shp_config(params_vdev, - &new_params->shp_cfg); - if (module_en_update & ISPP_MODULE_SHP) - shp_enable(params_vdev, - !!(module_ens & ISPP_MODULE_SHP), - &new_params->shp_cfg); + nr_params = (struct rkispp_params_nrcfg *)param_head; + if (module_cfg_update & ISPP_MODULE_NR) + nr_config(params_vdev, + &nr_params->nr_cfg); + if (module_en_update & ISPP_MODULE_NR) + nr_enable(params_vdev, + !!(module_ens & ISPP_MODULE_NR), + &nr_params->nr_cfg); - if (module_cfg_update & ISPP_MODULE_FEC) - fec_config(params_vdev, - &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_SHP) + shp_config(params_vdev, + &nr_params->shp_cfg); + if (module_en_update & ISPP_MODULE_SHP) + shp_enable(params_vdev, + !!(module_ens & ISPP_MODULE_SHP), + &nr_params->shp_cfg); - if (module_cfg_update & ISPP_MODULE_ORB) - orb_config(params_vdev, - &new_params->orb_cfg); - if (module_en_update & ISPP_MODULE_ORB) - orb_enable(params_vdev, - !!(module_ens & ISPP_MODULE_ORB)); + if (module_cfg_update & ISPP_MODULE_ORB) + orb_config(params_vdev, + &nr_params->orb_cfg); + if (module_en_update & ISPP_MODULE_ORB) + orb_enable(params_vdev, + !!(module_ens & ISPP_MODULE_ORB)); + } else { + struct rkispp_params_feccfg *fec_params; + + fec_params = (struct rkispp_params_feccfg *)param_head; + if (module_cfg_update & ISPP_MODULE_FEC) + fec_config(params_vdev, + &fec_params->fec_cfg); + if (module_en_update & ISPP_MODULE_FEC) + fec_enable(params_vdev, + !!(module_ens & ISPP_MODULE_FEC)); + } vb2_buffer_done(¶ms_vdev->cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); @@ -696,38 +755,6 @@ static void rkispp_params_cfg(struct rkispp_params_vdev *params_vdev, u32 frame_ spin_unlock(¶ms_vdev->config_lock); } - -static void params_vb2_buf_queue(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - struct rkispp_buffer *params_buf = to_rkispp_buffer(vbuf); - struct vb2_queue *vq = vb->vb2_queue; - struct rkispp_params_vdev *params_vdev = vq->drv_priv; - struct rkispp_stream_vdev *stream_vdev = ¶ms_vdev->dev->stream_vdev; - struct rkispp_params_cfg *new_params; - unsigned long flags; - - new_params = (struct rkispp_params_cfg *)vb2_plane_vaddr(vb, 0); - spin_lock_irqsave(¶ms_vdev->config_lock, flags); - if (params_vdev->first_params) { - params_vdev->first_params = false; - 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; - - } - wake_up(¶ms_vdev->dev->sync_onoff); - } - spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); - - new_params->module_init_ens = stream_vdev->module_ens; - params_buf->vaddr[0] = new_params; - spin_lock_irqsave(¶ms_vdev->config_lock, flags); - list_add_tail(¶ms_buf->queue, ¶ms_vdev->params); - spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); -} - static struct rkispp_params_ops rkispp_params_ops = { .rkispp_params_cfg = rkispp_params_cfg, .rkispp_params_vb2_buf_queue = params_vb2_buf_queue, diff --git a/drivers/media/platform/rockchip/ispp/regs.h b/drivers/media/platform/rockchip/ispp/regs.h index bc9f66766e0c..4a4eb91fc122 100644 --- a/drivers/media/platform/rockchip/ispp/regs.h +++ b/drivers/media/platform/rockchip/ispp/regs.h @@ -316,6 +316,7 @@ #define RKISPP_FEC_WR_UV_BASE_SHD (RKISPP_FEC + 0x0048) #define RKISPP_FEC_FBCE_HEAD_OFFSET (RKISPP_FEC + 0x0050) #define RKISPP_FEC_CORE_CTRL (RKISPP_FEC + 0x0080) +#define RKISPP_FEC_PIC_SIZE (RKISPP_FEC + 0x0088) #define RKISPP_FEC_DST_SIZE (RKISPP_FEC + 0x0088) #define RKISPP_FEC_MESH_SIZE (RKISPP_FEC + 0x008C) #define RKISPP_FEC_DMA_STATUS (RKISPP_FEC + 0x0090) diff --git a/drivers/media/platform/rockchip/ispp/stats.c b/drivers/media/platform/rockchip/ispp/stats.c index 0b0a2cff271e..9398234a36bc 100644 --- a/drivers/media/platform/rockchip/ispp/stats.c +++ b/drivers/media/platform/rockchip/ispp/stats.c @@ -22,12 +22,12 @@ static void update_addr(struct rkispp_stats_vdev *stats_vdev) struct rkispp_dummy_buffer *dummy_buf; u32 addr; - if (stats_vdev->next_buf) { - addr = stats_vdev->next_buf->buff_addr[0]; + if (stats_vdev->curr_buf) { + addr = stats_vdev->curr_buf->buff_addr[0]; rkispp_write(stats_vdev->dev, RKISPP_ORB_WR_BASE, addr); } - if (!stats_vdev->next_buf) { + if (!stats_vdev->curr_buf) { dummy_buf = &stats_vdev->dev->hw_dev->dummy_buf; if (!dummy_buf->mem_priv) return; @@ -40,44 +40,59 @@ static int rkispp_stats_frame_end(struct rkispp_stats_vdev *stats_vdev) { void __iomem *base = stats_vdev->dev->hw_dev->base_addr; struct rkispp_device *dev = stats_vdev->dev; - struct rkispp_buffer *curr_buf; - struct rkispp_stats_buffer *cur_stat_buf; + struct rkispp_stream_vdev *vdev = &dev->stream_vdev; unsigned long lock_flags = 0; if (stats_vdev->curr_buf) { + u32 payload_size = 0; u64 ns = ktime_get_ns(); - u32 total_num = readl(base + RKISPP_ORB_TOTAL_NUM); - u32 cur_frame_id = dev->ispp_sdev.frm_sync_seq; - void *vaddr; + u32 cur_frame_id = stats_vdev->frame_id; + struct rkispp_buffer *curr_buf = stats_vdev->curr_buf; + void *vaddr = vb2_plane_vaddr(&curr_buf->vb.vb2_buf, 0); - curr_buf = stats_vdev->curr_buf; - vaddr = vb2_plane_vaddr(&curr_buf->vb.vb2_buf, 0); - cur_stat_buf = (struct rkispp_stats_buffer *)vaddr; + if (stats_vdev->vdev_id == STATS_VDEV_TNR) { + struct rkispp_stats_tnrbuf *tnrbuf = vaddr; + + payload_size = sizeof(struct rkispp_stats_tnrbuf); + tnrbuf->frame_id = cur_frame_id; + tnrbuf->gain.index = -1; + tnrbuf->gainkg.index = -1; + if (vdev->tnr.cur_wr) { + tnrbuf->gain.index = vdev->tnr.cur_wr->didx[GROUP_BUF_GAIN]; + tnrbuf->gain.size = vdev->tnr.cur_wr->dbuf[GROUP_BUF_GAIN]->size; + tnrbuf->gainkg.index = vdev->tnr.buf.gain_kg.index; + tnrbuf->gainkg.size = vdev->tnr.buf.gain_kg.size; + } + } else if (stats_vdev->vdev_id == STATS_VDEV_NR) { + struct rkispp_stats_nrbuf *nrbuf = vaddr; + + payload_size = sizeof(struct rkispp_stats_nrbuf); + nrbuf->total_num = readl(base + RKISPP_ORB_TOTAL_NUM); + nrbuf->frame_id = cur_frame_id; + nrbuf->image.index = -1; + if (vdev->nr.cur_wr) { + nrbuf->image.index = vdev->nr.cur_wr->index; + nrbuf->image.size = vdev->nr.cur_wr->size; + } + } - cur_stat_buf->total_num = total_num; - cur_stat_buf->meas_type = ISPP_MODULE_ORB; - cur_stat_buf->frame_id = cur_frame_id; curr_buf->vb.vb2_buf.timestamp = ns; curr_buf->vb.sequence = cur_frame_id; - vb2_set_plane_payload(&curr_buf->vb.vb2_buf, 0, - sizeof(struct rkispp_stats_buffer)); - - vb2_buffer_done(&curr_buf->vb.vb2_buf, - VB2_BUF_STATE_DONE); + vb2_set_plane_payload(&curr_buf->vb.vb2_buf, 0, payload_size); + vb2_buffer_done(&curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); stats_vdev->curr_buf = NULL; } - stats_vdev->curr_buf = stats_vdev->next_buf; - stats_vdev->next_buf = NULL; spin_lock_irqsave(&stats_vdev->irq_lock, lock_flags); if (!list_empty(&stats_vdev->stat)) { - stats_vdev->next_buf = list_first_entry(&stats_vdev->stat, + stats_vdev->curr_buf = list_first_entry(&stats_vdev->stat, struct rkispp_buffer, queue); - list_del(&stats_vdev->next_buf->queue); + list_del(&stats_vdev->curr_buf->queue); } spin_unlock_irqrestore(&stats_vdev->irq_lock, lock_flags); - update_addr(stats_vdev); + if (stats_vdev->vdev_id == STATS_VDEV_NR) + update_addr(stats_vdev); return 0; } @@ -195,8 +210,15 @@ static int rkispp_stats_vb2_queue_setup(struct vb2_queue *vq, *num_buffers = clamp_t(u32, *num_buffers, RKISPP_STATS_REQ_BUFS_MIN, RKISPP_STATS_REQ_BUFS_MAX); - sizes[0] = sizeof(struct rkispp_stats_buffer); - + switch (stats_vdev->vdev_id) { + case STATS_VDEV_TNR: + sizes[0] = sizeof(struct rkispp_stats_tnrbuf); + break; + case STATS_VDEV_NR: + default: + sizes[0] = sizeof(struct rkispp_stats_nrbuf); + break; + } INIT_LIST_HEAD(&stats_vdev->stat); return 0; @@ -219,13 +241,7 @@ static void rkispp_stats_vb2_buf_queue(struct vb2_buffer *vb) buf->buff_addr[0] = vb2_dma_contig_plane_dma_addr(vb, 0); } spin_lock_irqsave(&stats_dev->irq_lock, lock_flags); - if (stats_dev->streamon && - !stats_dev->next_buf) { - stats_dev->next_buf = buf; - update_addr(stats_dev); - } else { - list_add_tail(&buf->queue, &stats_dev->stat); - } + list_add_tail(&buf->queue, &stats_dev->stat); spin_unlock_irqrestore(&stats_dev->irq_lock, lock_flags); } @@ -238,10 +254,6 @@ static void destroy_buf_queue(struct rkispp_stats_vdev *stats_vdev, list_add_tail(&stats_vdev->curr_buf->queue, &stats_vdev->stat); stats_vdev->curr_buf = NULL; } - if (stats_vdev->next_buf) { - list_add_tail(&stats_vdev->next_buf->queue, &stats_vdev->stat); - stats_vdev->next_buf = NULL; - } while (!list_empty(&stats_vdev->stat)) { buf = list_first_entry(&stats_vdev->stat, struct rkispp_buffer, queue); @@ -308,7 +320,7 @@ static int rkispp_stats_init_vb2_queue(struct vb2_queue *q, return vb2_queue_init(q); } -void rkispp_stats_isr(struct rkispp_stats_vdev *stats_vdev, u32 mis) +void rkispp_stats_isr(struct rkispp_stats_vdev *stats_vdev) { spin_lock(&stats_vdev->irq_lock); if (!stats_vdev->streamon) { @@ -317,30 +329,47 @@ void rkispp_stats_isr(struct rkispp_stats_vdev *stats_vdev, u32 mis) } spin_unlock(&stats_vdev->irq_lock); - if (mis & ORB_INT) - rkispp_stats_frame_end(stats_vdev); + rkispp_stats_frame_end(stats_vdev); } static void rkispp_init_stats_vdev(struct rkispp_stats_vdev *stats_vdev) { - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISPP_STAT; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkispp_stats_buffer); + stats_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISPP_STAT; + switch (stats_vdev->vdev_id) { + case STATS_VDEV_TNR: + stats_vdev->vdev_fmt.fmt.meta.buffersize = + sizeof(struct rkispp_stats_tnrbuf); + break; + case STATS_VDEV_NR: + default: + stats_vdev->vdev_fmt.fmt.meta.buffersize = + sizeof(struct rkispp_stats_nrbuf); + break; + } } -int rkispp_register_stats_vdev(struct rkispp_device *dev) +static int rkispp_register_stats_vdev(struct rkispp_device *dev, + enum rkispp_statsvdev_id vdev_id) { - struct rkispp_stats_vdev *stats_vdev = &dev->stats_vdev; + struct rkispp_stats_vdev *stats_vdev = &dev->stats_vdev[vdev_id]; struct rkispp_vdev_node *node = &stats_vdev->vnode; struct video_device *vdev = &node->vdev; int ret; stats_vdev->dev = dev; + stats_vdev->vdev_id = vdev_id; INIT_LIST_HEAD(&stats_vdev->stat); spin_lock_init(&stats_vdev->irq_lock); - strlcpy(vdev->name, "rkispp-stats", sizeof(vdev->name)); + switch (vdev_id) { + case STATS_VDEV_TNR: + strncpy(vdev->name, "rkispp_tnr_stats", sizeof(vdev->name) - 1); + break; + case STATS_VDEV_NR: + default: + strncpy(vdev->name, "rkispp_nr_stats", sizeof(vdev->name) - 1); + break; + } vdev->ioctl_ops = &rkispp_stats_ioctl; vdev->fops = &rkispp_stats_fops; @@ -375,9 +404,10 @@ err_release_queue: return ret; } -void rkispp_unregister_stats_vdev(struct rkispp_device *dev) +static void rkispp_unregister_stats_vdev(struct rkispp_device *dev, + enum rkispp_statsvdev_id vdev_id) { - struct rkispp_stats_vdev *stats_vdev = &dev->stats_vdev; + struct rkispp_stats_vdev *stats_vdev = &dev->stats_vdev[vdev_id]; struct rkispp_vdev_node *node = &stats_vdev->vnode; struct video_device *vdev = &node->vdev; @@ -386,3 +416,30 @@ void rkispp_unregister_stats_vdev(struct rkispp_device *dev) vb2_queue_release(vdev->queue); } +int rkispp_register_stats_vdevs(struct rkispp_device *dev) +{ + int ret = 0; + + if (dev->ispp_ver != ISPP_V10) + return 0; + + ret = rkispp_register_stats_vdev(dev, STATS_VDEV_TNR); + if (ret) + return ret; + + ret = rkispp_register_stats_vdev(dev, STATS_VDEV_NR); + if (ret) { + rkispp_unregister_stats_vdev(dev, STATS_VDEV_TNR); + return ret; + } + + return ret; +} + +void rkispp_unregister_stats_vdevs(struct rkispp_device *dev) +{ + if (dev->ispp_ver != ISPP_V10) + return; + rkispp_unregister_stats_vdev(dev, STATS_VDEV_TNR); + rkispp_unregister_stats_vdev(dev, STATS_VDEV_NR); +} diff --git a/drivers/media/platform/rockchip/ispp/stats.h b/drivers/media/platform/rockchip/ispp/stats.h index e4d43bf25bde..deb141e2a6d0 100644 --- a/drivers/media/platform/rockchip/ispp/stats.h +++ b/drivers/media/platform/rockchip/ispp/stats.h @@ -18,6 +18,12 @@ enum rkispp_stats_readout_cmd { RKISPP_READOUT_STATS, }; +enum rkispp_statsvdev_id { + STATS_VDEV_TNR = 0, + STATS_VDEV_NR, + STATS_VDEV_MAX +}; + struct rkispp_stats_readout_work { enum rkispp_stats_readout_cmd readout; unsigned long long timestamp; @@ -35,19 +41,20 @@ struct rkispp_stats_readout_work { struct rkispp_stats_vdev { struct rkispp_vdev_node vnode; struct rkispp_device *dev; + enum rkispp_statsvdev_id vdev_id; spinlock_t irq_lock; struct list_head stat; struct rkispp_buffer *curr_buf; - struct rkispp_buffer *next_buf; struct v4l2_format vdev_fmt; + u32 frame_id; bool streamon; }; -void rkispp_stats_isr(struct rkispp_stats_vdev *stats_vdev, u32 mis); +void rkispp_stats_isr(struct rkispp_stats_vdev *stats_vdev); -int rkispp_register_stats_vdev(struct rkispp_device *dev); +int rkispp_register_stats_vdevs(struct rkispp_device *dev); -void rkispp_unregister_stats_vdev(struct rkispp_device *dev); +void rkispp_unregister_stats_vdevs(struct rkispp_device *dev); #endif /* _RKISPP_STATS_H */ diff --git a/drivers/media/platform/rockchip/ispp/stream.c b/drivers/media/platform/rockchip/ispp/stream.c index 7070f5b295f5..f73daab142dc 100644 --- a/drivers/media/platform/rockchip/ispp/stream.c +++ b/drivers/media/platform/rockchip/ispp/stream.c @@ -484,16 +484,20 @@ void *get_list_buf(struct list_head *list, bool is_isp_ispp) void rkispp_start_3a_run(struct rkispp_device *dev) { - struct rkispp_params_vdev *params_vdev = &dev->params_vdev; - struct video_device *vdev = ¶ms_vdev->vnode.vdev; + struct rkispp_params_vdev *params_vdev; + struct video_device *vdev; struct v4l2_event ev = { .type = CIFISP_V4L2_EVENT_STREAM_START, }; int ret; + if (dev->ispp_ver == ISPP_V10) + params_vdev = &dev->params_vdev[PARAM_VDEV_NR]; + else + params_vdev = &dev->params_vdev[PARAM_VDEV_FEC]; if (!params_vdev->is_subs_evt) return; - + vdev = ¶ms_vdev->vnode.vdev; v4l2_event_queue(vdev, &ev); ret = wait_event_timeout(dev->sync_onoff, params_vdev->streamon && !params_vdev->first_params, @@ -508,16 +512,20 @@ void rkispp_start_3a_run(struct rkispp_device *dev) static void rkispp_stop_3a_run(struct rkispp_device *dev) { - struct rkispp_params_vdev *params_vdev = &dev->params_vdev; - struct video_device *vdev = ¶ms_vdev->vnode.vdev; + struct rkispp_params_vdev *params_vdev; + struct video_device *vdev; struct v4l2_event ev = { .type = CIFISP_V4L2_EVENT_STREAM_STOP, }; int ret; + if (dev->ispp_ver == ISPP_V10) + params_vdev = &dev->params_vdev[PARAM_VDEV_NR]; + else + params_vdev = &dev->params_vdev[PARAM_VDEV_FEC]; if (!params_vdev->is_subs_evt) return; - + vdev = ¶ms_vdev->vnode.vdev; v4l2_event_queue(vdev, &ev); ret = wait_event_timeout(dev->sync_onoff, !params_vdev->streamon, msecs_to_jiffies(1000)); @@ -1092,10 +1100,10 @@ static int rkispp_start_streaming(struct vb2_queue *queue, return ret; } - if (dev->inp == INP_DDR && - !atomic_read(&hw->refcnt) && + if (!atomic_read(&hw->refcnt) && !atomic_read(&dev->stream_vdev.refcnt) && - clk_get_rate(hw->clks[0]) <= hw->core_clk_min) { + clk_get_rate(hw->clks[0]) <= hw->core_clk_min && + (dev->inp == INP_DDR || dev->ispp_ver == ISPP_V20)) { dev->hw_dev->is_first = false; rkispp_set_clk_rate(hw->clks[0], hw->core_clk_max); } @@ -1868,11 +1876,13 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev) (dev->isp_mode & ISP_ISPP_QUICK)) ++dev->ispp_sdev.frm_sync_seq; - if (mis_val & TNR_INT) + if (mis_val & TNR_INT) { if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM) rkispp_clear_bits(dev, RKISPP_TNR_CTRL, SW_TNR_1ST_FRM); - - rkispp_stats_isr(&dev->stats_vdev, mis_val); + rkispp_stats_isr(&dev->stats_vdev[STATS_VDEV_TNR]); + } + if (mis_val & NR_INT) + rkispp_stats_isr(&dev->stats_vdev[STATS_VDEV_NR]); for (i = 0; i <= STREAM_S2; i++) { stream = &vdev->stream[i]; @@ -1893,7 +1903,7 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev) } } - if ((mis_val & NR_INT || mis_val & FEC_INT) && dev->hw_dev->is_first) { + if (mis_val & NR_INT && dev->hw_dev->is_first) { dev->mis_val = mis_val; INIT_WORK(&dev->irq_work, irq_work); schedule_work(&dev->irq_work); diff --git a/drivers/media/platform/rockchip/ispp/stream.h b/drivers/media/platform/rockchip/ispp/stream.h index 8ffde026109d..45fdf27b6d9f 100644 --- a/drivers/media/platform/rockchip/ispp/stream.h +++ b/drivers/media/platform/rockchip/ispp/stream.h @@ -247,8 +247,6 @@ struct rkispp_stream_vdev { }; int rkispp_get_tnrbuf_fd(struct rkispp_device *dev, struct rkispp_buf_idxfd *idxfd); -void rkispp_sendbuf_to_nr(struct rkispp_device *dev, - struct rkispp_tnr_inf *tnr_inf); void rkispp_set_trigger_mode(struct rkispp_device *dev, struct rkispp_trigger_mode *mode); void rkispp_isr(u32 mis_val, struct rkispp_device *dev); diff --git a/drivers/media/platform/rockchip/ispp/stream_v10.c b/drivers/media/platform/rockchip/ispp/stream_v10.c index 9a6ed6d89fda..95a1b38deb9f 100644 --- a/drivers/media/platform/rockchip/ispp/stream_v10.c +++ b/drivers/media/platform/rockchip/ispp/stream_v10.c @@ -146,20 +146,6 @@ static bool is_en_done_early(struct rkispp_device *dev) return en; } -static void rkispp_tnr_complete(struct rkispp_device *dev, struct rkispp_tnr_inf *inf) -{ - struct rkispp_subdev *ispp_sdev = &dev->ispp_sdev; - struct v4l2_event ev = { - .type = RKISPP_V4L2_EVENT_TNR_COMPLETE, - }; - struct rkispp_tnr_inf *tnr_inf; - - tnr_inf = (struct rkispp_tnr_inf *)ev.u.data; - memcpy(tnr_inf, inf, sizeof(*tnr_inf)); - - v4l2_subdev_notify_event(&ispp_sdev->sd, &ev); -} - static void tnr_free_buf(struct rkispp_device *dev) { struct rkispp_stream_vdev *vdev = &dev->stream_vdev; @@ -663,6 +649,7 @@ static int config_fec(struct rkispp_device *dev) static int config_modules(struct rkispp_device *dev) { + struct rkispp_params_vdev *params_vdev; int ret; v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev, @@ -687,7 +674,12 @@ static int config_modules(struct rkispp_device *dev) goto free_nr; /* config default params */ - dev->params_vdev.params_ops->rkispp_params_cfg(&dev->params_vdev, 0); + params_vdev = &dev->params_vdev[PARAM_VDEV_TNR]; + params_vdev->params_ops->rkispp_params_cfg(params_vdev, 0); + params_vdev = &dev->params_vdev[PARAM_VDEV_NR]; + params_vdev->params_ops->rkispp_params_cfg(params_vdev, 0); + params_vdev = &dev->params_vdev[PARAM_VDEV_FEC]; + params_vdev->params_ops->rkispp_params_cfg(params_vdev, 0); return 0; free_nr: nr_free_buf(dev); @@ -716,6 +708,7 @@ static void nr_work_event(struct rkispp_device *dev, struct rkispp_dummy_buffer *buf_wr, bool is_isr) { + struct rkispp_params_vdev *params_vdev = &dev->params_vdev[PARAM_VDEV_NR]; struct rkispp_stream_vdev *vdev = &dev->stream_vdev; struct rkispp_stream *stream = &vdev->stream[STREAM_II]; struct rkispp_monitor *monitor = &vdev->monitor; @@ -881,6 +874,8 @@ static void nr_work_event(struct rkispp_device *dev, dev->ispp_sdev.frame_timestamp = timestamp; dev->ispp_sdev.frm_sync_seq = seq; } + dev->stats_vdev[STATS_VDEV_NR].frame_id = seq; + params_vdev->params_ops->rkispp_params_cfg(params_vdev, seq); } /* check MB config and output buf beforce start, when MB connect to SHARP @@ -1032,6 +1027,7 @@ static void tnr_work_event(struct rkispp_device *dev, struct rkisp_ispp_buf *buf_wr, bool is_isr) { + struct rkispp_params_vdev *params_vdev = &dev->params_vdev[PARAM_VDEV_TNR]; struct rkispp_stream_vdev *vdev = &dev->stream_vdev; struct rkispp_stream *stream = &vdev->stream[STREAM_II]; struct rkispp_monitor *monitor = &vdev->monitor; @@ -1043,8 +1039,7 @@ static void tnr_work_event(struct rkispp_device *dev, struct dma_buf *dbuf; unsigned long lock_flags = 0, lock_flags1 = 0; u32 val, size = sizeof(vdev->tnr.buf) / sizeof(*dummy); - bool is_3to1 = vdev->tnr.is_3to1, is_start = false; - bool is_en = rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN; + bool is_en, is_3to1 = vdev->tnr.is_3to1, is_start = false; struct rkisp_ispp_reg *reg_buf = NULL; if (!(vdev->module_ens & ISPP_MODULE_TNR) || @@ -1054,6 +1049,11 @@ static void tnr_work_event(struct rkispp_device *dev, if (dev->inp == INP_ISP) sd = dev->ispp_sdev.remote_sd; + if (buf_rd) + params_vdev->params_ops->rkispp_params_cfg(params_vdev, buf_rd->frame_id); + + is_en = rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN; + spin_lock_irqsave(&vdev->tnr.buf_lock, lock_flags); /* event from tnr frame end */ @@ -1074,24 +1074,15 @@ static void tnr_work_event(struct rkispp_device *dev, } if (vdev->tnr.cur_wr) { - struct rkispp_tnr_inf tnr_inf; - if (!vdev->tnr.cur_wr->is_move_judge || !vdev->tnr.is_trigger) { /* tnr write buf to nr */ rkispp_module_work_event(dev, vdev->tnr.cur_wr, NULL, ISPP_MODULE_NR, is_isr); } else { - tnr_inf.dev_id = dev->dev_id; - tnr_inf.frame_id = vdev->tnr.cur_wr->frame_id; - tnr_inf.gainkg_idx = vdev->tnr.buf.gain_kg.index; - tnr_inf.gainwr_idx = vdev->tnr.cur_wr->didx[GROUP_BUF_GAIN]; - tnr_inf.gainkg_size = vdev->tnr.buf.gain_kg.size; dbuf = vdev->tnr.cur_wr->dbuf[GROUP_BUF_GAIN]; dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size); - tnr_inf.gainwr_size = dummy->size; rkispp_finish_buffer(dev, dummy); rkispp_finish_buffer(dev, &vdev->tnr.buf.gain_kg); - rkispp_tnr_complete(dev, &tnr_inf); list_add_tail(&vdev->tnr.cur_wr->list, &vdev->tnr.list_rpt); } vdev->tnr.cur_wr = NULL; @@ -1233,6 +1224,7 @@ static void tnr_work_event(struct rkispp_device *dev, vdev->tnr.cur_wr->is_move_judge = vdev->tnr.nxt_rd->is_move_judge; } + dev->stats_vdev[STATS_VDEV_TNR].frame_id = seq; } if (!dev->hw_dev->is_single) @@ -1294,6 +1286,7 @@ static void fec_work_event(struct rkispp_device *dev, void *buff_rd, bool is_isr, bool is_quick) { + struct rkispp_params_vdev *params_vdev = &dev->params_vdev[PARAM_VDEV_FEC]; struct rkispp_stream_vdev *vdev = &dev->stream_vdev; struct rkispp_monitor *monitor = &vdev->monitor; struct list_head *list = &vdev->fec.list_rd; @@ -1362,6 +1355,7 @@ static void fec_work_event(struct rkispp_device *dev, dev->ispp_sdev.frame_timestamp = vdev->fec.dummy_cur_rd->timestamp; dev->ispp_sdev.frm_sync_seq = seq; + params_vdev->params_ops->rkispp_params_cfg(params_vdev, seq); } else { seq = vdev->nr.buf.wr[0].id; dev->ispp_sdev.frame_timestamp = @@ -1453,41 +1447,6 @@ restart_unlock: } -void rkispp_sendbuf_to_nr(struct rkispp_device *dev, - struct rkispp_tnr_inf *tnr_inf) -{ - struct rkispp_stream_vdev *vdev = &dev->stream_vdev; - struct rkispp_dummy_buffer *dummy; - struct rkisp_ispp_buf *cur_buf; - unsigned long lock_flags = 0; - bool find_flg = false; - struct dma_buf *dbuf; - u32 size; - - size = sizeof(vdev->tnr.buf) / sizeof(*dummy); - spin_lock_irqsave(&vdev->tnr.buf_lock, lock_flags); - list_for_each_entry(cur_buf, &vdev->tnr.list_rpt, list) { - if (cur_buf->index == tnr_inf->dev_id && - cur_buf->didx[GROUP_BUF_GAIN] == tnr_inf->gainwr_idx) { - find_flg = true; - break; - } - } - - if (find_flg) { - list_del(&cur_buf->list); - - dbuf = cur_buf->dbuf[GROUP_BUF_GAIN]; - dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size); - rkispp_prepare_buffer(dev, dummy); - - /* tnr write buf to nr */ - rkispp_module_work_event(dev, cur_buf, NULL, - ISPP_MODULE_NR, false); - } - spin_unlock_irqrestore(&vdev->tnr.buf_lock, lock_flags); -} - void rkispp_set_trigger_mode(struct rkispp_device *dev, struct rkispp_trigger_mode *mode) { diff --git a/drivers/media/platform/rockchip/ispp/stream_v20.c b/drivers/media/platform/rockchip/ispp/stream_v20.c index 728a9c0afdf8..cd78a9aa9c95 100644 --- a/drivers/media/platform/rockchip/ispp/stream_v20.c +++ b/drivers/media/platform/rockchip/ispp/stream_v20.c @@ -57,6 +57,7 @@ static void update_mi(struct rkispp_stream *stream) static int config_fec(struct rkispp_device *dev) { + struct rkispp_params_vdev *params_vdev = &dev->params_vdev[PARAM_VDEV_FEC]; struct rkispp_stream_vdev *vdev; struct rkispp_stream *stream = NULL; struct rkispp_fec_head *fec_data; @@ -101,17 +102,13 @@ static int config_fec(struct rkispp_device *dev) rkispp_write(dev, RKISPP_FEC_RD_VIR_STRIDE, ALIGN(in_width * mult, 16) >> 2); rkispp_write(dev, RKISPP_FEC_SRC_SIZE, in_height << 16 | in_width); - fec_data = (struct rkispp_fec_head *)dev->params_vdev.buf_fec[0].vaddr; + fec_data = (struct rkispp_fec_head *)params_vdev->buf_fec[0].vaddr; if (fec_data) { - rkispp_prepare_buffer(dev, &dev->params_vdev.buf_fec[0]); - addrxf = - dev->params_vdev.buf_fec[0].dma_addr + fec_data->meshxf_oft; - addryf = - dev->params_vdev.buf_fec[0].dma_addr + fec_data->meshyf_oft; - addrxi = - dev->params_vdev.buf_fec[0].dma_addr + fec_data->meshxi_oft; - addryi = - dev->params_vdev.buf_fec[0].dma_addr + fec_data->meshyi_oft; + rkispp_prepare_buffer(dev, ¶ms_vdev->buf_fec[0]); + addrxf = params_vdev->buf_fec[0].dma_addr + fec_data->meshxf_oft; + addryf = params_vdev->buf_fec[0].dma_addr + fec_data->meshyf_oft; + addrxi = params_vdev->buf_fec[0].dma_addr + fec_data->meshxi_oft; + addryi = params_vdev->buf_fec[0].dma_addr + fec_data->meshyi_oft; rkispp_write(dev, RKISPP_FEC_MESH_XFRA_BASE, addrxf); rkispp_write(dev, RKISPP_FEC_MESH_YFRA_BASE, addryf); rkispp_write(dev, RKISPP_FEC_MESH_XINT_BASE, addrxi); @@ -167,6 +164,7 @@ static void fec_free_buf(struct rkispp_device *dev) static int config_modules(struct rkispp_device *dev) { + struct rkispp_params_vdev *params_vdev; int ret; v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev, @@ -182,7 +180,8 @@ static int config_modules(struct rkispp_device *dev) goto free_fec; /* config default params */ - dev->params_vdev.params_ops->rkispp_params_cfg(&dev->params_vdev, 0); + params_vdev = &dev->params_vdev[PARAM_VDEV_FEC]; + params_vdev->params_ops->rkispp_params_cfg(params_vdev, 0); return 0; free_fec: diff --git a/include/uapi/linux/rkispp-config.h b/include/uapi/linux/rkispp-config.h index b4a27f74f9c9..8d9d31e92906 100644 --- a/include/uapi/linux/rkispp-config.h +++ b/include/uapi/linux/rkispp-config.h @@ -81,26 +81,27 @@ #define FEC_MESH_XY_NUM 131072 #define FEC_MESH_BUF_NUM 2 -#define TNR_BUF_IDXFD_NUM 64 +#define MAX_BUF_IDXFD_NUM 64 /************VIDIOC_PRIVATE*************/ +#define RKISPP_CMD_SET_INIT_MODULE \ + _IOW('V', BASE_VIDIOC_PRIVATE + 0, int) + #define RKISPP_CMD_GET_FECBUF_INFO \ - _IOR('V', BASE_VIDIOC_PRIVATE + 0, struct rkispp_fecbuf_info) + _IOR('V', BASE_VIDIOC_PRIVATE + 1, struct rkispp_fecbuf_info) #define RKISPP_CMD_SET_FECBUF_SIZE \ - _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct rkispp_fecbuf_size) - -#define RKISPP_CMD_FEC_IN_OUT \ - _IOW('V', BASE_VIDIOC_PRIVATE + 10, struct rkispp_fec_in_out) - -#define RKISPP_CMD_TRIGGER_YNRRUN \ - _IOW('V', BASE_VIDIOC_PRIVATE + 11, struct rkispp_tnr_inf) - -#define RKISPP_CMD_GET_TNRBUF_FD \ - _IOR('V', BASE_VIDIOC_PRIVATE + 12, struct rkispp_buf_idxfd) + _IOW('V', BASE_VIDIOC_PRIVATE + 2, struct rkispp_fecbuf_size) #define RKISPP_CMD_TRIGGER_MODE \ - _IOW('V', BASE_VIDIOC_PRIVATE + 13, struct rkispp_trigger_mode) + _IOW('V', BASE_VIDIOC_PRIVATE + 3, struct rkispp_trigger_mode) + +#define RKISPP_CMD_GET_TNRBUF_FD \ + _IOR('V', BASE_VIDIOC_PRIVATE + 4, struct rkispp_buf_idxfd) + +/**independent fec video**/ +#define RKISPP_CMD_FEC_IN_OUT \ + _IOW('V', BASE_VIDIOC_PRIVATE + 10, struct rkispp_fec_in_out) /************EVENT_PRIVATE**************/ #define RKISPP_V4L2_EVENT_TNR_COMPLETE \ @@ -119,19 +120,10 @@ struct rkispp_fec_in_out { int mesh_yfra_fd; }; -struct rkispp_tnr_inf { - u32 dev_id; - u32 frame_id; - u32 gainkg_idx; - u32 gainwr_idx; - u32 gainkg_size; - u32 gainwr_size; -} __attribute__ ((packed)); - struct rkispp_buf_idxfd { u32 buf_num; - u32 index[TNR_BUF_IDXFD_NUM]; - s32 dmafd[TNR_BUF_IDXFD_NUM]; + u32 index[MAX_BUF_IDXFD_NUM]; + s32 dmafd[MAX_BUF_IDXFD_NUM]; } __attribute__ ((packed)); struct rkispp_trigger_mode { @@ -321,27 +313,61 @@ struct rkispp_orb_config { u32 max_feature __attribute__((aligned(4))); } __attribute__ ((packed)); +struct rkispp_buf_info { + //s32 fd; + u32 index; + u32 size; +} __attribute__ ((packed)); + /** - * struct rkispp_params_cfg - Rockchip ISPP Input Parameters Meta Data + * struct rkispp_params_cfghead - Rockchip ISPP Input Parameters Meta Data * * @module_en_update: mask the enable bits of which module should be updated * @module_ens: mask the enable value of each module, only update the module * which correspond bit was set in module_en_update * @module_cfg_update: mask the config bits of which module should be updated - * @module_init_en: initial enable module function */ -struct rkispp_params_cfg { +struct rkispp_params_cfghead { u32 module_en_update; u32 module_ens; u32 module_cfg_update; - u32 module_init_ens; u32 frame_id; +} __attribute__ ((packed)); + +/** + * struct rkispp_params_tnrcfg - Rockchip ISPP Input Parameters Meta Data + */ +struct rkispp_params_tnrcfg { + struct rkispp_params_cfghead head; + struct rkispp_tnr_config tnr_cfg; + //struct rkispp_buf_info gain; + //struct rkispp_buf_info image; +} __attribute__ ((packed)); + +/** + * struct rkispp_params_nrcfg - Rockchip ISPP Input Parameters Meta Data + */ +struct rkispp_params_nrcfg { + struct rkispp_params_cfghead head; + struct rkispp_nr_config nr_cfg; struct rkispp_sharp_config shp_cfg; - struct rkispp_fec_config fec_cfg; struct rkispp_orb_config orb_cfg; + + struct rkispp_buf_info gain; + //struct rkispp_buf_info image; +} __attribute__ ((packed)); + +/** + * struct rkispp_params_feccfg - Rockchip ISPP Input Parameters Meta Data + */ +struct rkispp_params_feccfg { + struct rkispp_params_cfghead head; + + struct rkispp_fec_config fec_cfg; + struct rkispp_buf_info image; } __attribute__ ((packed)); struct rkispp_orb_data { @@ -353,18 +379,35 @@ struct rkispp_orb_data { } __attribute__ ((packed)); /** - * struct rkispp_stats_buffer - Rockchip ISPP Statistics + * struct rkispp_stats_nrbuf - Rockchip ISPP Statistics * * @meas_type: measurement types * @frame_id: frame ID for sync * @data: statistics data */ -struct rkispp_stats_buffer { +struct rkispp_stats_nrbuf { struct rkispp_orb_data data[ORB_DATA_NUM]; u32 total_num __attribute__((aligned(4))); u32 meas_type; u32 frame_id; + + struct rkispp_buf_info image; +} __attribute__ ((packed)); + +/** + * struct rkispp_stats_tnrbuf - Rockchip ISPP Statistics + * + * @meas_type: measurement types + * @frame_id: frame ID for sync + */ +struct rkispp_stats_tnrbuf { + u32 meas_type; + u32 frame_id; + + struct rkispp_buf_info gain; + struct rkispp_buf_info gainkg; + //struct rkispp_buf_info image; } __attribute__ ((packed)); #endif