From ddff1a93bac277b1a0ba14c601d5236c3c36365d Mon Sep 17 00:00:00 2001 From: Krishnankutty Kolathappilly Date: Mon, 2 May 2016 23:46:14 -0700 Subject: msm: cpp: Query buffer from buffer manager based on index Query buffer from buffer manager based on buf index. This allows modules to provide a buffer associated with a particular request and avoids a wrong buffer from being returned. CRs-Fixed: 1018651 Change-Id: I206f3fa334d96e9f57fcbd985922a436ed701ff3 Signed-off-by: Krishnankutty Kolathappilly Signed-off-by: Hariram Purushothaman --- .../platform/msm/camera_v2/pproc/cpp/Makefile | 1 + .../platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 183 +++++++++++++++++---- .../platform/msm/camera_v2/pproc/cpp/msm_cpp.h | 3 +- 3 files changed, 152 insertions(+), 35 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile index 56880f4d5676..2198352143f7 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile @@ -2,4 +2,5 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2 ccflags-y += -Idrivers/media/platform/msm/camera_v2/isp/ ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io ccflags-y += -Idrivers/media/platform/msm/camera_v2/common +ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_buf_mgr/ obj-$(CONFIG_MSM_CPP) += msm_cpp_soc.o msm_cpp.o diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 32eb883ed6c0..5a1e99adc7f3 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -83,8 +83,27 @@ if (IS_BATCH_BUFFER_ON_PREVIEW(new_frame)) \ iden = swap_iden; \ } + +#define SWAP_BUF_INDEX_FOR_BATCH_ON_PREVIEW(new_frame, buff_mgr_info, \ + cur_index, swap_index) { \ + if (IS_BATCH_BUFFER_ON_PREVIEW(new_frame)) \ + buff_mgr_info.index = swap_index; \ + else \ + buff_mgr_info.index = cur_index; \ +} + +/* + * Default value for get buf to be used - 0xFFFFFFFF + * 0 is a valid index + * no valid index from userspace, use last buffer from queue. + */ +#define DEFAULT_OUTPUT_BUF_INDEX 0xFFFFFFFF +#define IS_DEFAULT_OUTPUT_BUF_INDEX(index) \ + ((index == DEFAULT_OUTPUT_BUF_INDEX) ? 1 : 0) + static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev, - uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info); + uint32_t buff_mgr_ops, uint32_t ids, void *arg); + static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev, struct msm_queue_cmd *frame_qcmd); static int msm_cpp_send_command_to_hardware(struct cpp_device *cpp_dev, @@ -92,6 +111,9 @@ static int msm_cpp_send_command_to_hardware(struct cpp_device *cpp_dev, static int msm_cpp_update_gdscr_status(struct cpp_device *cpp_dev, bool status); +static int msm_cpp_buffer_private_ops(struct cpp_device *cpp_dev, + uint32_t buff_mgr_ops, uint32_t id, void *arg); + #if CONFIG_MSM_CPP_DBG #define CPP_DBG(fmt, args...) pr_err(fmt, ##args) #else @@ -802,12 +824,9 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev) pr_err("%s: irq request fail\n", __func__); goto req_irq_fail; } - cpp_dev->buf_mgr_subdev = msm_buf_mngr_get_subdev(); - - rc = msm_cpp_buffer_ops(cpp_dev, - VIDIOC_MSM_BUF_MNGR_INIT, NULL); + rc = msm_cam_buf_mgr_register_ops(&cpp_dev->buf_mgr_ops); if (rc < 0) { - pr_err("buf mngr init failed\n"); + pr_err("buf mngr req ops failed\n"); msm_camera_unregister_irq(cpp_dev->pdev, cpp_dev->irq, cpp_dev); goto req_irq_fail; @@ -878,12 +897,6 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev) { int32_t rc; if (cpp_dev->state != CPP_STATE_BOOT) { - rc = msm_cpp_buffer_ops(cpp_dev, - VIDIOC_MSM_BUF_MNGR_DEINIT, NULL); - if (rc < 0) { - pr_err("error in buf mngr deinit\n"); - rc = -EINVAL; - } msm_camera_unregister_irq(cpp_dev->pdev, cpp_dev->irq, cpp_dev); tasklet_kill(&cpp_dev->cpp_tasklet); atomic_set(&cpp_dev->irq_cnt, 0); @@ -1193,12 +1206,28 @@ static const struct v4l2_subdev_internal_ops msm_cpp_internal_ops = { }; static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev, - uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info) + uint32_t buff_mgr_ops, uint32_t ids, + void *arg) { int rc = -EINVAL; - rc = v4l2_subdev_call(cpp_dev->buf_mgr_subdev, core, ioctl, - buff_mgr_ops, buff_mgr_info); + switch (buff_mgr_ops) { + case VIDIOC_MSM_BUF_MNGR_IOCTL_CMD: { + rc = msm_cpp_buffer_private_ops(cpp_dev, buff_mgr_ops, + ids, arg); + break; + } + case VIDIOC_MSM_BUF_MNGR_PUT_BUF: + case VIDIOC_MSM_BUF_MNGR_BUF_DONE: + case VIDIOC_MSM_BUF_MNGR_GET_BUF: + default: { + struct msm_buf_mngr_info *buff_mgr_info = + (struct msm_buf_mngr_info *)arg; + rc = cpp_dev->buf_mgr_ops.msm_cam_buf_mgr_ops(buff_mgr_ops, + buff_mgr_info); + break; + } + } if (rc < 0) pr_debug("%s: line %d rc = %d\n", __func__, __LINE__, rc); return rc; @@ -1242,9 +1271,9 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev, SWAP_IDENTITY_FOR_BATCH_ON_PREVIEW(processed_frame, iden, processed_frame->duplicate_identity); - memset(&buff_mgr_info, 0 , sizeof(struct msm_buf_mngr_info)); + buff_mgr_info.session_id = ((iden >> 16) & 0xFFFF); buff_mgr_info.stream_id = (iden & 0xFFFF); buff_mgr_info.frame_id = processed_frame->frame_id; @@ -1262,7 +1291,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev, if (put_buf) { rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_PUT_BUF, - &buff_mgr_info); + 0x0, &buff_mgr_info); if (rc < 0) { pr_err("error putting buffer\n"); rc = -EINVAL; @@ -1270,7 +1299,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev, } else { rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE, - &buff_mgr_info); + 0x0, &buff_mgr_info); if (rc < 0) { pr_err("error putting buffer\n"); rc = -EINVAL; @@ -1289,6 +1318,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev, memset(&buff_mgr_info, 0 , sizeof(struct msm_buf_mngr_info)); + buff_mgr_info.session_id = ((iden >> 16) & 0xFFFF); buff_mgr_info.stream_id = (iden & 0xFFFF); buff_mgr_info.frame_id = processed_frame->frame_id; @@ -1298,7 +1328,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev, if (put_buf) { rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_PUT_BUF, - &buff_mgr_info); + 0x0, &buff_mgr_info); if (rc < 0) { pr_err("error putting buffer\n"); rc = -EINVAL; @@ -1306,7 +1336,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev, } else { rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE, - &buff_mgr_info); + 0x0, &buff_mgr_info); if (rc < 0) { pr_err("error putting buffer\n"); rc = -EINVAL; @@ -2158,6 +2188,8 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, uint8_t tnr_enabled; enum msm_camera_buf_mngr_buf_type buf_type = MSM_CAMERA_BUF_MNGR_BUF_PLANAR; + uint32_t ioctl_cmd, idx; + uint32_t op_index, dup_index; stripe_base = cpp_dev->payload_params.stripe_base; stripe_size = cpp_dev->payload_params.stripe_size; @@ -2212,8 +2244,12 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, goto frame_msg_err; } + op_index = new_frame->output_buffer_info[0].index; + dup_index = new_frame->duplicate_buffer_info.index; + if (new_frame->we_disable == 0) { int32_t iden = new_frame->identity; + if ((new_frame->output_buffer_info[0].native_buff == 0) && (new_frame->first_payload)) { memset(&buff_mgr_info, 0, @@ -2226,16 +2262,32 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, SWAP_IDENTITY_FOR_BATCH_ON_PREVIEW(new_frame, iden, new_frame->duplicate_identity); + /* + * Swap the input buffer index for batch mode with + * buffer on preview + */ + SWAP_BUF_INDEX_FOR_BATCH_ON_PREVIEW(new_frame, + buff_mgr_info, op_index, dup_index); + buff_mgr_info.session_id = ((iden >> 16) & 0xFFFF); buff_mgr_info.stream_id = (iden & 0xFFFF); buff_mgr_info.type = buf_type; + + if (IS_DEFAULT_OUTPUT_BUF_INDEX(buff_mgr_info.index)) { + ioctl_cmd = VIDIOC_MSM_BUF_MNGR_GET_BUF; + idx = 0x0; + } else { + ioctl_cmd = VIDIOC_MSM_BUF_MNGR_IOCTL_CMD; + idx = + MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX; + } rc = msm_cpp_buffer_ops(cpp_dev, - VIDIOC_MSM_BUF_MNGR_GET_BUF, - &buff_mgr_info); + ioctl_cmd, idx, &buff_mgr_info); if (rc < 0) { rc = -EAGAIN; - pr_debug("%s: error getting buffer rc:%d\n", - __func__, rc); + pr_debug("%s:get_buf err rc:%d, index %d\n", + __func__, rc, + new_frame->output_buffer_info[0].index); goto frame_msg_err; } num_output_bufs = @@ -2273,16 +2325,32 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, iden, new_frame->identity); memset(&dup_buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info)); + + /* + * Swap the input buffer index for batch mode with + * buffer on preview + */ + SWAP_BUF_INDEX_FOR_BATCH_ON_PREVIEW(new_frame, + dup_buff_mgr_info, dup_index, op_index); + dup_buff_mgr_info.session_id = ((iden >> 16) & 0xFFFF); dup_buff_mgr_info.stream_id = (iden & 0xFFFF); dup_buff_mgr_info.type = MSM_CAMERA_BUF_MNGR_BUF_PLANAR; - rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF, + if (IS_DEFAULT_OUTPUT_BUF_INDEX(dup_buff_mgr_info.index)) { + ioctl_cmd = VIDIOC_MSM_BUF_MNGR_GET_BUF; + idx = 0x0; + } else { + ioctl_cmd = VIDIOC_MSM_BUF_MNGR_IOCTL_CMD; + idx = MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX; + } + rc = msm_cpp_buffer_ops(cpp_dev, ioctl_cmd, idx, &dup_buff_mgr_info); if (rc < 0) { rc = -EAGAIN; - pr_debug("%s: error getting buffer rc:%d\n", - __func__, rc); + pr_debug("%s: get_buf err rc:%d, index %d\n", + __func__, rc, + new_frame->duplicate_buffer_info.index); goto phyaddr_err; } new_frame->duplicate_buffer_info.index = @@ -2296,7 +2364,7 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, pr_err("error gettting output physical address\n"); rc = -EINVAL; msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_PUT_BUF, - &dup_buff_mgr_info); + 0x0, &dup_buff_mgr_info); goto phyaddr_err; } /* set duplicate enable bit */ @@ -2374,7 +2442,7 @@ qcmd_err: phyaddr_err: if (new_frame->output_buffer_info[0].native_buff == 0) msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_PUT_BUF, - &buff_mgr_info); + 0x0, &buff_mgr_info); frame_msg_err: kfree(cpp_frame_msg); kfree(new_frame); @@ -2985,11 +3053,11 @@ STREAM_BUFF_END: if (queue_buf_info.is_buf_dirty) { rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_PUT_BUF, - &queue_buf_info.buff_mgr_info); + 0x0, &queue_buf_info.buff_mgr_info); } else { rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE, - &queue_buf_info.buff_mgr_info); + 0x0, &queue_buf_info.buff_mgr_info); } if (rc < 0) { pr_err("error in buf done\n"); @@ -3001,6 +3069,7 @@ STREAM_BUFF_END: case VIDIOC_MSM_CPP_POP_STREAM_BUFFER: { struct msm_buf_mngr_info buff_mgr_info; struct msm_cpp_frame_info_t frame_info; + uint32_t ioctl_cmd, idx; if (ioctl_ptr->ioctl_ptr == NULL || (ioctl_ptr->len != sizeof(struct msm_cpp_frame_info_t))) { @@ -3020,16 +3089,25 @@ STREAM_BUFF_END: buff_mgr_info.stream_id = (frame_info.identity & 0xFFFF); buff_mgr_info.type = MSM_CAMERA_BUF_MNGR_BUF_PLANAR; - rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF, + if (IS_DEFAULT_OUTPUT_BUF_INDEX( + frame_info.output_buffer_info[0].index)) { + ioctl_cmd = VIDIOC_MSM_BUF_MNGR_GET_BUF; + idx = 0x0; + } else { + ioctl_cmd = VIDIOC_MSM_BUF_MNGR_IOCTL_CMD; + idx = MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX; + } + rc = msm_cpp_buffer_ops(cpp_dev, ioctl_cmd, idx, &buff_mgr_info); if (rc < 0) { rc = -EAGAIN; - pr_err_ratelimited("error getting buffer rc:%d\n", rc); + pr_err_ratelimited("POP: get_buf err rc:%d, index %d\n", + rc, frame_info.output_buffer_info[0].index); break; } buff_mgr_info.frame_id = frame_info.frame_id; rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE, - &buff_mgr_info); + 0x0, &buff_mgr_info); if (rc < 0) { pr_err("error in buf done\n"); rc = -EAGAIN; @@ -3813,6 +3891,43 @@ static void msm_cpp_set_vbif_reg_values(struct cpp_device *cpp_dev) } } +static int msm_cpp_buffer_private_ops(struct cpp_device *cpp_dev, + uint32_t buff_mgr_ops, uint32_t id, void *arg) { + + int32_t rc = 0; + + switch (id) { + case MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX: { + struct msm_camera_private_ioctl_arg ioctl_arg; + struct msm_buf_mngr_info *buff_mgr_info = + (struct msm_buf_mngr_info *)arg; + + ioctl_arg.id = MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX; + ioctl_arg.size = sizeof(struct msm_buf_mngr_info); + ioctl_arg.result = 0; + ioctl_arg.reserved = 0x0; + ioctl_arg.ioctl_ptr = 0x0; + MSM_CAM_GET_IOCTL_ARG_PTR(&ioctl_arg.ioctl_ptr, &buff_mgr_info, + sizeof(void *)); + rc = cpp_dev->buf_mgr_ops.msm_cam_buf_mgr_ops(buff_mgr_ops, + &ioctl_arg); + /* Use VIDIOC_MSM_BUF_MNGR_GET_BUF if getbuf with indx fails */ + if (rc < 0) { + pr_err_ratelimited("get_buf_by_idx for %d err %d,use get_buf\n", + buff_mgr_info->index, rc); + rc = cpp_dev->buf_mgr_ops.msm_cam_buf_mgr_ops( + VIDIOC_MSM_BUF_MNGR_GET_BUF, buff_mgr_info); + } + break; + } + default: { + pr_err("unsupported buffer manager ioctl\n"); + break; + } + } + return rc; +} + static int cpp_probe(struct platform_device *pdev) { struct cpp_device *cpp_dev; diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h index 753c6ffd810a..1784e27b1e37 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h @@ -19,6 +19,7 @@ #include #include #include +#include "msm_generic_buf_mgr.h" #include "msm_sd.h" #include "cam_soc_api.h" #include "cam_hw_ops.h" @@ -254,7 +255,7 @@ struct cpp_device { struct msm_cpp_buff_queue_info_t *buff_queue; uint32_t num_buffq; - struct v4l2_subdev *buf_mgr_subdev; + struct msm_cam_buf_mgr_req_ops buf_mgr_ops; uint32_t bus_client; uint32_t bus_idx; -- cgit v1.2.3