Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddff1a93 authored by Krishnankutty Kolathappilly's avatar Krishnankutty Kolathappilly Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarKrishnankutty Kolathappilly <kkolatha@codeaurora.org>
Signed-off-by: default avatarHariram Purushothaman <hariramp@codeaurora.org>
parent bb02457c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+149 −34
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <media/v4l2-subdev.h>
#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;