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

Commit 940e6eb6 authored by Krishnankutty Kolathappilly's avatar Krishnankutty Kolathappilly
Browse files

msm: cpp: Add support for batch mode on 8996



Retrieve the set group buffer command payload length and offset to
duplication indicator flag from DT. Update the payload with
distance parameter for ubwc. Send the set group buffer command
to hardware before sending the frame. This information is used
during batch HFR to update the output buffer address and also the
frame that needs to be duplicated.

Change-Id: I7d7bf7080614d55289228336843d44edd6e72733
Signed-off-by: default avatarKrishnankutty Kolathappilly <kkolatha@codeaurora.org>
parent dc1571a4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -50,6 +50,10 @@ Optional properties of the child node:
   mmu prefetch address min location in payload.
- qcom,ref-we-mmu-pf-ptr-off =  offset from plane base to reference write engine
   mmu prefetch address min location in payload.
- qcom,set-group-buffer-len = length/size of set group buffer command used for
  hfr.
- qcom,dup-frame-indicator-off =  offset for duplicate frame indicator in a
  batch for frames

Optional properties:
- mmagic-vdd-supply: phandle to GDSC regulator controlling mmagic.
@@ -108,5 +112,8 @@ Example:
			qcom,we-mmu-pf-ptr-off = <12>;
			qcom,dup-we-mmu-pf-ptr-off = <17>;
			qcom,ref-we-mmu-pf-ptr-off = <22>;
			qcom,set-group-buffer-len = <91>;
			qcom,dup-frame-indicator-off = <48>;

		};
	};
+132 −49
Original line number Diff line number Diff line
@@ -908,6 +908,10 @@ static int msm_cpp_read_payload_params_from_dt(struct cpp_device *cpp_dev)
			payload_params->dup_we_mmu_pf_ptr_off);
		CPP_DT_READ_U32(fw_info_node, "qcom,ref-we-mmu-pf-ptr-off",
			payload_params->ref_we_mmu_pf_ptr_off);
		CPP_DT_READ_U32(fw_info_node, "qcom,set-group-buffer-len",
			payload_params->set_group_buffer_len);
		CPP_DT_READ_U32(fw_info_node, "qcom,dup-frame-indicator-off",
			payload_params->dup_frame_indicator_off);
	} while (0);

no_binding:
@@ -2040,6 +2044,126 @@ exit:
	return;
}

static int32_t msm_cpp_set_group_buffer(struct cpp_device *cpp_dev,
	struct msm_cpp_frame_info_t *new_frame, unsigned long out_phyaddr,
	uint32_t num_output_bufs)
{

	uint32_t *set_group_buffer_w_duplication = NULL;
	uint32_t *ptr;
	unsigned long out_phyaddr0, out_phyaddr1, distance;
	int32_t rc = 0;
	uint32_t set_group_buffer_len, set_group_buffer_len_bytes,
		dup_frame_off, ubwc_enabled, i = 0;

	do {
		if (new_frame->batch_info.batch_mode != BATCH_MODE_VIDEO) {
			pr_debug("%s: batch mode not set %d\n", __func__,
				new_frame->batch_info.batch_mode);
			break;
		}

		if (new_frame->batch_info.batch_size <= 1) {
			pr_debug("%s: batch size is invalid %d\n", __func__,
				new_frame->batch_info.batch_size);
			break;
		}

		set_group_buffer_len =
			cpp_dev->payload_params.set_group_buffer_len;
		if (!set_group_buffer_len) {
			pr_err("%s: invalid set group buffer cmd len %d\n",
				 __func__, set_group_buffer_len);
			rc = -EINVAL;
			break;
		}

		/*
		 * Length of  MSM_CPP_CMD_GROUP_BUFFER command +
		 * 4 byte for header + 4 byte for the length field +
		 * 4 byte for the trailer + 4 byte for
		 * MSM_CPP_CMD_GROUP_BUFFER prefix before the payload
		 */
		set_group_buffer_len += 4;
		set_group_buffer_len_bytes = set_group_buffer_len *
			sizeof(uint32_t);
		set_group_buffer_w_duplication =
			kzalloc(set_group_buffer_len_bytes, GFP_KERNEL);
		if (!set_group_buffer_w_duplication) {
			pr_err("%s: set group buffer data alloc failed\n",
				__func__);
			rc = -ENOMEM;
			break;
		}

		memset(set_group_buffer_w_duplication, 0x0,
			set_group_buffer_len_bytes);
		dup_frame_off =
			cpp_dev->payload_params.dup_frame_indicator_off;
		/* Add a factor of 1 as command is prefixed to the payload. */
		dup_frame_off += 1;
		ubwc_enabled = ((new_frame->feature_mask & UBWC_MASK) >> 5);
		ptr = set_group_buffer_w_duplication;
		/*create and send Set Group Buffer with Duplicate command*/
		*ptr++ = MSM_CPP_CMD_GROUP_BUFFER;
		*ptr++ = MSM_CPP_MSG_ID_CMD;
		/*
		 * This field is the value read from dt and stands for length of
		 * actual data in payload
		 */
		*ptr++ = cpp_dev->payload_params.set_group_buffer_len;
		*ptr++ = MSM_CPP_CMD_GROUP_BUFFER;
		*ptr++ = 0;
		out_phyaddr0 = out_phyaddr;

		for (i = 1; i < num_output_bufs; i++) {
			out_phyaddr1 = 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_phyaddr1) {
				pr_err("%s: error getting o/p phy addr\n",
					__func__);
				rc = -EINVAL;
				break;
			}
			distance = out_phyaddr1 - out_phyaddr0;
			out_phyaddr0 = out_phyaddr1;
			*ptr++ = distance;
			*ptr++ = distance;
			*ptr++ = distance;
			if (ubwc_enabled)
				*ptr++ = distance;
		}
		if (rc)
			break;

		if (new_frame->duplicate_output)
			set_group_buffer_w_duplication[dup_frame_off] =
				1 << new_frame->batch_info.pick_preview_idx;
		else
			set_group_buffer_w_duplication[dup_frame_off] = 0;

		/*
		 * Index for cpp message id trailer is length of payload for
		 * set group buffer minus 1
		 */
		set_group_buffer_w_duplication[set_group_buffer_len - 1] =
			MSM_CPP_MSG_ID_TRAILER;
		rc = msm_cpp_send_command_to_hardware(cpp_dev,
			set_group_buffer_w_duplication, set_group_buffer_len);
		if (rc < 0) {
			pr_err("%s: Send Command Error rc %d\n", __func__, rc);
			break;
		}

	} while (0);

	kfree(set_group_buffer_w_duplication);
	return rc;
}

static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
	struct msm_cpp_frame_info_t *new_frame)
{
@@ -2052,7 +2176,7 @@ 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, num_output_bufs = 1;
	int32_t num_output_bufs = 1;
	int32_t stripe_base = 0;
	uint32_t stripe_size;
	uint8_t tnr_enabled;
@@ -2194,54 +2318,6 @@ 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 = ((new_frame->feature_mask & TNR_MASK) >> 2);
	if (tnr_enabled) {
		tnr_scratch_buffer0 = msm_cpp_fetch_buffer_info(cpp_dev,
@@ -2279,6 +2355,13 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
			tnr_scratch_buffer0;
	}

	rc = msm_cpp_set_group_buffer(cpp_dev, new_frame, out_phyaddr0,
		num_output_bufs);
	if (rc) {
		pr_err("%s: set group buffer failure %d\n", __func__, rc);
		goto phyaddr_err;
	}

	num_stripes = new_frame->last_stripe_index -
		new_frame->first_stripe_index + 1;
	cpp_frame_msg[1] = stripe_base - 2 + num_stripes * stripe_size;
+2 −1
Original line number Diff line number Diff line
@@ -90,7 +90,6 @@
#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;
@@ -192,6 +191,8 @@ struct msm_cpp_payload_params {
	uint32_t we_mmu_pf_ptr_off;
	uint32_t dup_we_mmu_pf_ptr_off;
	uint32_t ref_we_mmu_pf_ptr_off;
	uint32_t set_group_buffer_len;
	uint32_t dup_frame_indicator_off;
};

struct cpp_device {