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

Commit 7c530206 authored by Sagar Gore's avatar Sagar Gore Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: cpp: Changes to support batch mode



Support batch processing of buffers in CPP hardware.
Changes to parse through multiple buffers for CPP output.
Buffer manager will provide list of individual buffer index
via buf info struct, CPP driver will parse through all the
individual buffers to configure CPP firmware.

Change-Id: If780d32aee68960e392a9f4a0ba6fb1b3ddb6358
Signed-off-by: default avatarSagar Gore <sgore@codeaurora.org>
parent eb43795d
Loading
Loading
Loading
Loading
+175 −21
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,
	uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info);
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,
	uint32_t *cmd_msg, uint32_t payload_size);

#if CONFIG_MSM_CPP_DBG
#define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
@@ -1484,8 +1486,14 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
			buff_mgr_info.frame_id = processed_frame->frame_id;
			buff_mgr_info.timestamp = processed_frame->timestamp;
			buff_mgr_info.reserved = processed_frame->reserved;
			if (processed_frame->batch_info.batch_mode ==
				BATCH_MODE_VIDEO) {
				buff_mgr_info.index =
				processed_frame->output_buffer_info[0].index;
					processed_frame->batch_info.cont_idx;
			} else {
				buff_mgr_info.index = processed_frame->
					output_buffer_info[0].index;
			}
			if (put_buf) {
				rc = msm_cpp_buffer_ops(cpp_dev,
					VIDIOC_MSM_BUF_MNGR_PUT_BUF,
@@ -1507,7 +1515,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,

		if (processed_frame->duplicate_output  &&
			!processed_frame->
				output_buffer_info[1].processed_divert &&
				duplicate_buffer_info.processed_divert &&
			!processed_frame->we_disable) {
			memset(&buff_mgr_info, 0 ,
				sizeof(struct msm_buf_mngr_info));
@@ -1518,7 +1526,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
			buff_mgr_info.frame_id = processed_frame->frame_id;
			buff_mgr_info.timestamp = processed_frame->timestamp;
			buff_mgr_info.index =
				processed_frame->output_buffer_info[1].index;
				processed_frame->duplicate_buffer_info.index;
			if (put_buf) {
				rc = msm_cpp_buffer_ops(cpp_dev,
					VIDIOC_MSM_BUF_MNGR_PUT_BUF,
@@ -1566,7 +1574,7 @@ static int msm_cpp_dump_frame_cmd(struct msm_cpp_frame_info_t *frame_info)
		CPP_DBG("msg[%03d] = 0x%08x\n", i+i1,
			frame_info->cpp_cmd_msg[i+i1]);
	/* send trailer */
	CPP_DBG("msg[%03d] = 0x%08x\n", i+i1, 0xabcdefaa);
	CPP_DBG("msg[%03d] = 0x%08x\n", i+i1, MSM_CPP_MSG_ID_TRAILER);
	CPP_DBG("--   end: cpp frame cmd for identity=0x%x, frame_id=%d --\n",
		frame_info->identity, frame_info->frame_id);
	return 0;
@@ -1696,7 +1704,7 @@ static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev,
				cpp_dev->base);
		}
		/* send trailer */
		msm_cpp_write(0xabcdefaa, cpp_dev->base);
		msm_cpp_write(MSM_CPP_MSG_ID_TRAILER, cpp_dev->base);

		do_gettimeofday(&(process_frame->in_time));
		rc = 0;
@@ -1706,6 +1714,18 @@ static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev,
	return rc;
}

static int msm_cpp_send_command_to_hardware(struct cpp_device *cpp_dev,
	uint32_t *cmd_msg, uint32_t payload_size)
{
	uint32_t i;

	for (i = 0; i < payload_size; i++) {
		msm_cpp_write(cmd_msg[i],
			cpp_dev->base);
	}
	return 0;
}

static int msm_cpp_flush_frames(struct cpp_device *cpp_dev)
{
	return 0;
@@ -1765,6 +1785,35 @@ no_mem_err:
	return NULL;
}

static int msm_cpp_check_buf_type(struct msm_buf_mngr_info *buff_mgr_info,
	struct msm_cpp_frame_info_t *new_frame)
{
	int32_t num_output_bufs = 0;
	uint32_t i = 0;
	if (buff_mgr_info->type == MSM_CAMERA_BUF_MNGR_BUF_USER) {
		new_frame->batch_info.cont_idx =
			buff_mgr_info->index;
		num_output_bufs = buff_mgr_info->user_buf.buf_cnt;
		if (buff_mgr_info->user_buf.buf_cnt <
			new_frame->batch_info.batch_size) {
			/* Less bufs than Input buffer */
			num_output_bufs = buff_mgr_info->user_buf.buf_cnt;
		} else {
			/* More or equal bufs as Input buffer */
			num_output_bufs = new_frame->batch_info.batch_size;
		}
		for (i = 0; i < num_output_bufs; i++) {
			new_frame->output_buffer_info[i].index =
				buff_mgr_info->user_buf.buf_idx[i];
		}
	} else {
		/* For non-group case use first buf slot */
		new_frame->output_buffer_info[0].index = buff_mgr_info->index;
		num_output_bufs = 1;
	}

	return num_output_bufs;
}
static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
	struct msm_cpp_frame_info_t *new_frame)
{
@@ -1777,13 +1826,15 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
	uint16_t num_stripes = 0;
	struct msm_buf_mngr_info buff_mgr_info, dup_buff_mgr_info;
	int32_t in_fd;
	int32_t i = 0;
	int32_t i = 0, num_output_bufs = 1;
	int32_t stripe_base = 0;
	uint32_t rd_pntr, wr_0_pntr, wr_1_pntr, wr_2_pntr, wr_3_pntr;
	uint32_t wr_0_meta_data_wr_pntr, wr_1_meta_data_wr_pntr,
		wr_2_meta_data_wr_pntr, wr_3_meta_data_wr_pntr;
	uint32_t rd_ref_pntr, wr_ref_pntr, stripe_info_offset, stripe_size;
	uint8_t tnr_enabled, ubwc_enabled;
	enum msm_camera_buf_mngr_buf_type buf_type =
		MSM_CAMERA_BUF_MNGR_BUF_PLANAR;

	if (!new_frame) {
		pr_err("%s: Frame is Null\n", __func__);
@@ -1849,12 +1900,15 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
			(new_frame->first_payload)) {
			memset(&buff_mgr_info, 0,
				sizeof(struct msm_buf_mngr_info));
			if (new_frame->batch_info.batch_mode ==
				BATCH_MODE_VIDEO)
				buf_type = MSM_CAMERA_BUF_MNGR_BUF_USER;

			buff_mgr_info.session_id =
				((new_frame->identity >> 16) & 0xFFFF);
			buff_mgr_info.stream_id =
				(new_frame->identity & 0xFFFF);
			buff_mgr_info.type =
				MSM_CAMERA_BUF_MNGR_BUF_PLANAR;
			buff_mgr_info.type = buf_type;
			rc = msm_cpp_buffer_ops(cpp_dev,
				VIDIOC_MSM_BUF_MNGR_GET_BUF,
				&buff_mgr_info);
@@ -1864,8 +1918,15 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
					__func__, rc);
				goto frame_msg_err;
			}
			new_frame->output_buffer_info[0].index =
				buff_mgr_info.index;
			num_output_bufs =
				msm_cpp_check_buf_type(&buff_mgr_info,
					new_frame);
			if (!num_output_bufs) {
				pr_err("%s: error getting buffer %d\n",
					__func__, num_output_bufs);
				rc = -EINVAL;
				goto phyaddr_err;
			}
		}

		out_phyaddr0 = msm_cpp_fetch_buffer_info(cpp_dev,
@@ -1886,7 +1947,7 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
	if (new_frame->duplicate_output) {
		CPP_DBG("duplication enabled, dup_id=0x%x",
			new_frame->duplicate_identity);
		memset(&new_frame->output_buffer_info[1], 0,
		memset(&new_frame->duplicate_buffer_info, 0,
			sizeof(struct msm_cpp_buffer_info_t));
		memset(&dup_buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
		dup_buff_mgr_info.session_id =
@@ -1903,13 +1964,13 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
				__func__, rc);
			goto phyaddr_err;
		}
		new_frame->output_buffer_info[1].index =
		new_frame->duplicate_buffer_info.index =
			dup_buff_mgr_info.index;
		out_phyaddr1 = msm_cpp_fetch_buffer_info(cpp_dev,
			&new_frame->output_buffer_info[1],
			&new_frame->duplicate_buffer_info,
			((new_frame->duplicate_identity >> 16) & 0xFFFF),
			(new_frame->duplicate_identity & 0xFFFF),
			&new_frame->output_buffer_info[1].fd);
			&new_frame->duplicate_buffer_info.fd);
		if (!out_phyaddr1) {
			pr_err("error gettting output physical address\n");
			rc = -EINVAL;
@@ -1922,6 +1983,54 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
		CPP_DBG("out_phyaddr1= %08x\n", (uint32_t)out_phyaddr1);
	}

	if ((BATCH_MODE_VIDEO == new_frame->batch_info.batch_mode) &&
		(new_frame->batch_info.batch_size > 1)) {
		/*create and send Set Group Buffer with Duplicate command*/
		uint32_t set_group_buffer_w_duplication[73];
		uint32_t *ptr = &set_group_buffer_w_duplication[0];
		unsigned long out_phyaddr, out_phyaddr_new, distance;

		memset(ptr, 0, sizeof(set_group_buffer_w_duplication));
		*ptr++ = MSM_CPP_CMD_GROUP_BUFFER;
		*ptr++ = MSM_CPP_MSG_ID_CMD;
		*ptr++ = MSM_CPP_GROUP_CMD_LEN;
		*ptr++ = MSM_CPP_CMD_GROUP_BUFFER;
		*ptr++ = 0;
		out_phyaddr = out_phyaddr0;
		for (i = 1; i < num_output_bufs; i++) {
			out_phyaddr_new = msm_cpp_fetch_buffer_info(cpp_dev,
				&new_frame->output_buffer_info[i],
				((new_frame->identity >> 16) & 0xFFFF),
				(new_frame->identity & 0xFFFF),
				&new_frame->output_buffer_info[i].fd);
			if (!out_phyaddr_new) {
				pr_err("%s: error getting o/p phy addr\n",
					__func__);
				rc = -EINVAL;
				goto phyaddr_err;
			}
			distance = out_phyaddr_new - out_phyaddr;
			out_phyaddr = out_phyaddr_new;
			*ptr++ = distance;
			*ptr++ = distance;
			*ptr++ = distance;
		}
		if (new_frame->duplicate_output)
			set_group_buffer_w_duplication[38] =
				1 << new_frame->batch_info.pick_preview_idx;
		else
			set_group_buffer_w_duplication[38] = 0;

		set_group_buffer_w_duplication[72] = MSM_CPP_MSG_ID_TRAILER;
		rc = msm_cpp_send_command_to_hardware(cpp_dev,
			&set_group_buffer_w_duplication[0], 73);
		if (rc < 0) {
			pr_err("%s: Send Command Error\n", __func__);
			rc = -EINVAL;
			goto phyaddr_err;
		}
	}

	tnr_enabled = msm_cpp_is_tnr_enabled(cpp_dev, cpp_frame_msg);
	pr_debug("%s: feature_mask 0x%x\n", __func__, new_frame->feature_mask);
	ubwc_enabled = ((new_frame->feature_mask & 0x20) >> 5);
@@ -1984,8 +2093,10 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
		}
	}

	if (tnr_enabled)
		cpp_frame_msg[10] = out_phyaddr0 - in_phyaddr;
	if (tnr_enabled) {
		cpp_frame_msg[10] = tnr_scratch_buffer1 -
			tnr_scratch_buffer0;
	}

	num_stripes = new_frame->last_stripe_index -
		new_frame->first_stripe_index + 1;
@@ -2665,7 +2776,7 @@ static struct msm_cpp_frame_info_t *get_64bit_cpp_frame_from_compat(
	struct msm_cpp_frame_info_t *new_frame = NULL;
	uint32_t *cpp_frame_msg;
	void *cpp_cmd_msg_64bit;
	int32_t rc;
	int32_t rc, i;

	new_frame32 = kzalloc(sizeof(struct msm_cpp_frame_info32_t),
		GFP_KERNEL);
@@ -2718,6 +2829,20 @@ static struct msm_cpp_frame_info_t *get_64bit_cpp_frame_from_compat(
		new_frame32->output_buffer_info[0];
	new_frame->output_buffer_info[1] =
		new_frame32->output_buffer_info[1];
	new_frame->output_buffer_info[2] =
		new_frame32->output_buffer_info[2];
	new_frame->output_buffer_info[3] =
		new_frame32->output_buffer_info[3];
	new_frame->output_buffer_info[4] =
		new_frame32->output_buffer_info[4];
	new_frame->output_buffer_info[5] =
		new_frame32->output_buffer_info[5];
	new_frame->output_buffer_info[6] =
		new_frame32->output_buffer_info[6];
	new_frame->output_buffer_info[7] =
		new_frame32->output_buffer_info[7];
	new_frame->duplicate_buffer_info =
		new_frame32->duplicate_buffer_info;
	new_frame->tnr_scratch_buffer_info[0] =
		new_frame32->tnr_scratch_buffer_info[0];
	new_frame->tnr_scratch_buffer_info[1] =
@@ -2733,8 +2858,20 @@ static struct msm_cpp_frame_info_t *get_64bit_cpp_frame_from_compat(
	new_frame->last_payload = new_frame32->last_payload;
	new_frame->first_stripe_index = new_frame32->first_stripe_index;
	new_frame->last_stripe_index = new_frame32->last_stripe_index;
	new_frame->stripe_info_offset = new_frame32->stripe_info_offset;
	new_frame->stripe_info_offset =
		new_frame32->stripe_info_offset;
	new_frame->stripe_info = new_frame32->stripe_info;
	new_frame->batch_info.batch_mode =
		new_frame32->batch_info.batch_mode;
	new_frame->batch_info.batch_size =
		new_frame32->batch_info.batch_size;
	new_frame->batch_info.cont_idx =
		new_frame32->batch_info.cont_idx;
	for (i = 0; i < MAX_PLANES; i++)
		new_frame->batch_info.intra_plane_offset[i] =
			new_frame32->batch_info.intra_plane_offset[i];
	new_frame->batch_info.pick_preview_idx =
		new_frame32->batch_info.pick_preview_idx;

	/* Convert the 32 bit pointer to 64 bit pointer */
	new_frame->cookie = compat_ptr(new_frame32->cookie);
@@ -2780,6 +2917,8 @@ no_mem32:
static void get_compat_frame_from_64bit(struct msm_cpp_frame_info_t *frame,
	struct msm_cpp_frame_info32_t *k32_frame)
{
	int32_t i;

	k32_frame->frame_id = frame->frame_id;
	k32_frame->inst_id = frame->inst_id;
	k32_frame->client_id = frame->client_id;
@@ -2804,6 +2943,13 @@ static void get_compat_frame_from_64bit(struct msm_cpp_frame_info_t *frame,
	k32_frame->input_buffer_info = frame->input_buffer_info;
	k32_frame->output_buffer_info[0] = frame->output_buffer_info[0];
	k32_frame->output_buffer_info[1] = frame->output_buffer_info[1];
	k32_frame->output_buffer_info[2] = frame->output_buffer_info[2];
	k32_frame->output_buffer_info[3] = frame->output_buffer_info[3];
	k32_frame->output_buffer_info[4] = frame->output_buffer_info[4];
	k32_frame->output_buffer_info[5] = frame->output_buffer_info[5];
	k32_frame->output_buffer_info[6] = frame->output_buffer_info[6];
	k32_frame->output_buffer_info[7] = frame->output_buffer_info[7];
	k32_frame->duplicate_buffer_info = frame->duplicate_buffer_info;
	k32_frame->duplicate_output = frame->duplicate_output;
	k32_frame->we_disable = frame->we_disable;
	k32_frame->duplicate_identity = frame->duplicate_identity;
@@ -2817,6 +2963,14 @@ static void get_compat_frame_from_64bit(struct msm_cpp_frame_info_t *frame,
	k32_frame->last_stripe_index = frame->last_stripe_index;
	k32_frame->stripe_info_offset = frame->stripe_info_offset;
	k32_frame->stripe_info = frame->stripe_info;
	k32_frame->batch_info.batch_mode = frame->batch_info.batch_mode;
	k32_frame->batch_info.batch_size = frame->batch_info.batch_size;
	k32_frame->batch_info.cont_idx = frame->batch_info.cont_idx;
	for (i = 0; i < MAX_PLANES; i++)
		k32_frame->batch_info.intra_plane_offset[i] =
			frame->batch_info.intra_plane_offset[i];
	k32_frame->batch_info.pick_preview_idx =
		frame->batch_info.pick_preview_idx;
}

static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
@@ -3083,8 +3237,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
		cmd = MSM_SD_SHUTDOWN;
		break;
	default:
		pr_err_ratelimited("%s: unsupported compat type :%d\n",
				__func__, cmd);
		pr_err_ratelimited("%s: unsupported compat type :%x LOAD %lu\n",
				__func__, cmd, VIDIOC_MSM_CPP_LOAD_FIRMWARE);
		break;
	}

+2 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#define MSM_CPP_CMD_ERROR_REQUEST		0x9
#define MSM_CPP_CMD_GET_STATUS			0xA
#define MSM_CPP_CMD_GET_FW_VER			0xB
#define MSM_CPP_CMD_GROUP_BUFFER		0x12

#define MSM_CPP_MSG_ID_CMD          0x3E646D63
#define MSM_CPP_MSG_ID_OK           0x0A0A4B4F
@@ -89,6 +90,7 @@
#define MSM_CPP_TASKLETQ_SIZE		16
#define MSM_CPP_TX_FIFO_LEVEL		16
#define MSM_CPP_RX_FIFO_LEVEL		512
#define MSM_CPP_GROUP_CMD_LEN		69

struct cpp_subscribe_info {
	struct v4l2_fh *vfh;
+20 −2
Original line number Diff line number Diff line
@@ -176,6 +176,20 @@ struct msm_cpp_stream_buff_info_t {
	struct msm_cpp_buffer_info_t *buffer_info;
};

enum msm_cpp_batch_mode_t {
	BATCH_MODE_NONE,
	BATCH_MODE_VIDEO,
	BATCH_MODE_PREVIEW
};

struct msm_cpp_batch_info_t {
	enum msm_cpp_batch_mode_t  batch_mode;
	uint32_t batch_size;
	uint32_t intra_plane_offset[MAX_PLANES];
	uint32_t pick_preview_idx;
	uint32_t cont_idx;
};

struct msm_cpp_frame_info_t {
	int32_t frame_id;
	struct timeval timestamp;
@@ -197,7 +211,8 @@ struct msm_cpp_frame_info_t {
	uint32_t feature_mask;
	uint8_t we_disable;
	struct msm_cpp_buffer_info_t input_buffer_info;
	struct msm_cpp_buffer_info_t output_buffer_info[2];
	struct msm_cpp_buffer_info_t output_buffer_info[8];
	struct msm_cpp_buffer_info_t duplicate_buffer_info;
	struct msm_cpp_buffer_info_t tnr_scratch_buffer_info[2];
	uint32_t reserved;
	uint8_t partial_frame_indicator;
@@ -220,6 +235,7 @@ struct msm_cpp_frame_info_t {
	uint32_t last_stripe_index;
	uint32_t stripe_info_offset;
	uint32_t stripe_info;
	struct msm_cpp_batch_info_t  batch_info;
};

struct msm_cpp_pop_stream_info_t {
@@ -391,7 +407,8 @@ struct msm_cpp_frame_info32_t {
	uint32_t feature_mask;
	uint8_t we_disable;
	struct msm_cpp_buffer_info_t input_buffer_info;
	struct msm_cpp_buffer_info_t output_buffer_info[2];
	struct msm_cpp_buffer_info_t output_buffer_info[8];
	struct msm_cpp_buffer_info_t duplicate_buffer_info;
	struct msm_cpp_buffer_info_t tnr_scratch_buffer_info[2];
	uint32_t reserved;
	uint8_t partial_frame_indicator;
@@ -414,6 +431,7 @@ struct msm_cpp_frame_info32_t {
	uint32_t last_stripe_index;
	uint32_t stripe_info_offset;
	uint32_t stripe_info;
	struct msm_cpp_batch_info_t  batch_info;
};

struct msm_cpp_clock_settings32_t {