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

Commit dffb050c authored by Kiran Kumar H N's avatar Kiran Kumar H N Committed by Stephen Boyd
Browse files

msm: camera: Add support for instance handle based buffer lookup.



Currently when VFE requests for a free buffer, we search based
on the image mode sent from VFE. In some cases, there can be
multiple instances with the same image mode. This means the
buffer lookup logic has to take into consideration other
parameters like current usecase, vfe operation mode etc.
To ease this, add support for buffer lookup based on
the instance handle. The instance handle contains information
about where to get the buffer from. So the buffer lookup
logic does not have to know about other details. The instance
handle is decided when the user sets the format for a particular
instance. It is passed on to the VFE during AXI configuration.
VFE stores this and sends it whenever it requests for a free
buffer for a particular output.
Keep the current image_mode based buffer lookup logic for
legacy targets.

Change-Id: I78c3db77ac4014365c9866ff780ec71ac4c7ff87
Signed-off-by: default avatarKiran Kumar H N <hurlisal@codeaurora.org>
parent ca10d8a3
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -92,6 +92,33 @@ static int msm_camera_v4l2_queryctrl(struct file *f, void *pctx,
	return rc;
}

static int msm_camera_v4l2_private_g_ctrl(struct file *f, void *pctx,
	struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
{
	int rc = -EINVAL;
	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
	struct msm_cam_v4l2_dev_inst *pcam_inst;
	pcam_inst = container_of(f->private_data,
		struct msm_cam_v4l2_dev_inst, eventHandle);

	WARN_ON(pctx != f->private_data);

	mutex_lock(&pcam->vid_lock);
	switch (ioctl_ptr->id) {
	case MSM_V4L2_PID_INST_HANDLE:
		COPY_TO_USER(rc, (void __user *)ioctl_ptr->ioctl_ptr,
			(void *)&pcam_inst->inst_handle, sizeof(uint32_t));
		if (rc)
			ERR_COPY_TO_USER();
		break;
	default:
		pr_err("%s Unsupported ioctl %d ", __func__, ioctl_ptr->id);
		break;
	}
	mutex_unlock(&pcam->vid_lock);
	return rc;
}

static int msm_camera_v4l2_g_ctrl(struct file *f, void *pctx,
					struct v4l2_control *c)
{
@@ -686,7 +713,9 @@ static int msm_camera_v4l2_s_parm(struct file *f, void *pctx,
	struct msm_cam_v4l2_dev_inst *pcam_inst;
	pcam_inst = container_of(f->private_data,
		struct msm_cam_v4l2_dev_inst, eventHandle);
	pcam_inst->image_mode = a->parm.capture.extendedmode;
	pcam_inst->image_mode = (a->parm.capture.extendedmode & 0x7F);
	SET_IMG_MODE(pcam_inst->inst_handle, pcam_inst->image_mode);
	SET_VIDEO_INST_IDX(pcam_inst->inst_handle, pcam_inst->my_index);
	pcam_inst->pcam->dev_inst_map[pcam_inst->image_mode] = pcam_inst;
	pcam_inst->path = msm_vidbuf_get_path(pcam_inst->image_mode);
	D("%spath=%d,rc=%d\n", __func__,
@@ -745,6 +774,12 @@ static long msm_camera_v4l2_private_ioctl(struct file *file, void *fh,
	case MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL:
		rc = msm_camera_v4l2_private_s_ctrl(file, fh, ioctl_ptr);
		break;
	case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
		rc = msm_camera_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
		break;
	default:
		pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
		break;
	}
	return rc;
}
@@ -1055,6 +1090,8 @@ static int msm_close(struct file *f)
		v4l2_fh_del(&pcam_inst->eventHandle);
		v4l2_fh_exit(&pcam_inst->eventHandle);
	}
	CLR_VIDEO_INST_IDX(pcam_inst->inst_handle);
	CLR_IMG_MODE(pcam_inst->inst_handle);
	mutex_unlock(&pcam_inst->inst_lock);
	mutex_destroy(&pcam_inst->inst_lock);
	kfree(pcam_inst);
+46 −40
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ struct isp_msg_stats {

struct msm_free_buf {
	uint8_t num_planes;
	int32_t image_mode;
	uint32_t inst_handle;
	uint32_t ch_paddr[VIDEO_MAX_PLANES];
	uint32_t vb;
};
@@ -323,7 +323,7 @@ struct msm_cam_v4l2_dev_inst {
	enum v4l2_mbus_pixelcode sensor_pxlcode;
	struct msm_cam_v4l2_device *pcam;
	int my_index;
	int image_mode;
	uint32_t image_mode;
	int path;
	int buf_count;
	/* buffer offsets, if any */
@@ -335,6 +335,7 @@ struct msm_cam_v4l2_dev_inst {
	struct img_plane_info plane_info;
	int vbqueue_initialized;
	struct mutex inst_lock;
	uint32_t inst_handle;
};

struct msm_cam_mctl_node {
@@ -547,6 +548,18 @@ struct msm_cam_server_dev {
	struct msm_cam_server_irqmap_entry hw_irqmap[CAMERA_SS_IRQ_MAX];
};

enum msm_cam_buf_lookup_type {
	BUF_LOOKUP_INVALID,
	BUF_LOOKUP_BY_IMG_MODE,
	BUF_LOOKUP_BY_INST_HANDLE,
};

struct msm_cam_buf_handle {
	uint16_t buf_lookup_type;
	uint32_t image_mode;
	uint32_t inst_handle;
};

/* ISP related functions */
void msm_isp_vfe_dev_init(struct v4l2_subdev *vd);
/*
@@ -562,16 +575,19 @@ int msm_mctl_free(struct msm_cam_v4l2_device *pcam);
int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam);
int msm_mctl_init_user_formats(struct msm_cam_v4l2_device *pcam);
int msm_mctl_buf_done(struct msm_cam_media_controller *pmctl,
			int msg_type, struct msm_free_buf *buf,
	struct msm_cam_buf_handle *buf_handle,
	struct msm_free_buf *buf,
	uint32_t frame_id);
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
	int msg_type, struct msm_free_buf *frame, int dirty, int node_type);
	struct msm_cam_buf_handle *buf_handle,
	struct msm_free_buf *frame, int dirty, int node_type);
int msm_mctl_reserve_free_buf(struct msm_cam_media_controller *pmctl,
	struct msm_cam_v4l2_dev_inst *pcam_inst,
				int path, struct msm_free_buf *free_buf);
	struct msm_cam_buf_handle *buf_handle,
	struct msm_free_buf *free_buf);
int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
	struct msm_cam_v4l2_dev_inst *pcam_inst,
				int path, struct msm_free_buf *free_buf);
	struct msm_free_buf *free_buf);
/*Memory(PMEM) functions*/
int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
	struct ion_client *client);
@@ -582,13 +598,11 @@ int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount);
uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
					int pmem_type,
					struct msm_pmem_region *reg,
	int pmem_type, struct msm_pmem_region *reg,
	uint8_t maxcount);
unsigned long msm_pmem_stats_vtop_lookup(
	struct msm_cam_media_controller *mctl,
				unsigned long buffer,
				int fd);
	unsigned long buffer, int fd);
unsigned long msm_pmem_stats_ptov_lookup(
	struct msm_cam_media_controller *mctl,
	unsigned long addr, int *fd);
@@ -615,23 +629,15 @@ int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
struct msm_frame_buffer *msm_mctl_buf_find(
	struct msm_cam_media_controller *pmctl,
	struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
	int msg_type, struct msm_free_buf *fbuf);
	struct msm_free_buf *fbuf);
void msm_mctl_gettimeofday(struct timeval *tv);
struct msm_frame_buffer *msm_mctl_get_free_buf(
		struct msm_cam_media_controller *pmctl,
		int msg_type);
int msm_mctl_put_free_buf(
		struct msm_cam_media_controller *pmctl,
		int msg_type, struct msm_frame_buffer *buf);
int msm_mctl_check_pp(struct msm_cam_media_controller *p_mctl,
	int msg_type, int *pp_divert_type, int *pp_type);
int msm_mctl_do_pp_divert(
	struct msm_cam_media_controller *p_mctl,
	int msg_type, struct msm_free_buf *fbuf,
	struct msm_cam_buf_handle *buf_handle,
	struct msm_free_buf *fbuf,
	uint32_t frame_id, int pp_type);
int msm_mctl_buf_del(struct msm_cam_media_controller *pmctl,
	int msg_type,
	struct msm_frame_buffer *my_buf);
int msm_mctl_pp_release_free_frame(
	struct msm_cam_media_controller *p_mctl,
	void __user *arg);
@@ -651,7 +657,7 @@ int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam);
struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
	struct msm_cam_media_controller *pmctl,
		int image_mode);
	struct msm_cam_buf_handle *buf_handle);
int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
	int image_mode, struct msm_frame_buffer *buf);
int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
+23 −15
Original line number Diff line number Diff line
@@ -168,7 +168,9 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
	struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
	struct msm_frame_info *frame_info =
		(struct msm_frame_info *)vdata->evt_msg.data;
	uint32_t vfe_id, image_mode;
	uint32_t vfe_id;
	struct msm_cam_buf_handle buf_handle;

	if (!pcam) {
		pr_debug("%s pcam is null. return\n", __func__);
		msm_isp_sync_free(vdata);
@@ -176,10 +178,13 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
	}
	if (frame_info) {
		vfe_id = frame_info->path;
		image_mode = frame_info->image_mode;
		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
		buf_handle.inst_handle = frame_info->inst_handle;
	} else {
		vfe_id = vdata->evt_msg.msg_id;
		image_mode = msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
		buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
		buf_handle.image_mode =
			msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
	}

	switch (vdata->type) {
@@ -189,14 +194,14 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
		D("%s Got V32_START_*: Getting ping addr id = %d",
						__func__, vfe_id);
		msm_mctl_reserve_free_buf(pmctl, NULL,
					image_mode, &free_buf);
					&buf_handle, &free_buf);
		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
		cfgcmd.value = &vfe_id;
		vfe_params.vfe_cfg = &cfgcmd;
		vfe_params.data = (void *)&free_buf;
		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
		msm_mctl_reserve_free_buf(pmctl, NULL,
					image_mode, &free_buf);
					&buf_handle, &free_buf);
		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
		cfgcmd.value = &vfe_id;
		vfe_params.vfe_cfg = &cfgcmd;
@@ -208,7 +213,7 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
		pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
						__func__, vfe_id);
		msm_mctl_reserve_free_buf(pmctl, NULL,
					image_mode, &free_buf);
					&buf_handle, &free_buf);
		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
		cfgcmd.value = &vfe_id;
		vfe_params.vfe_cfg = &cfgcmd;
@@ -216,7 +221,7 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
		temp_free_buf = free_buf;
		if (msm_mctl_reserve_free_buf(pmctl, NULL,
					image_mode, &free_buf)) {
					&buf_handle, &free_buf)) {
			/* Write the same buffer into PONG */
			free_buf = temp_free_buf;
		}
@@ -254,7 +259,7 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
		D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
						__func__, vfe_id);
		msm_mctl_reserve_free_buf(pmctl, NULL,
					image_mode, &free_buf);
					&buf_handle, &free_buf);
		cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
		cfgcmd.value = &vfe_id;
		vfe_params.vfe_cfg = &cfgcmd;
@@ -320,10 +325,10 @@ static int msm_isp_notify_vfe(struct v4l2_subdev *sd,
	}
	case NOTIFY_VFE_MSG_OUT: {
		uint8_t msgid;
		int32_t image_mode = -1;
		struct msm_cam_buf_handle buf_handle;
		struct isp_msg_output *isp_output =
				(struct isp_msg_output *)arg;
		if (isp_output->buf.image_mode < 0) {
		if (!isp_output->buf.inst_handle) {
			switch (isp_output->output_id) {
			case MSG_ID_OUTPUT_P:
				msgid = VFE_MSG_OUTPUT_P;
@@ -356,19 +361,22 @@ static int msm_isp_notify_vfe(struct v4l2_subdev *sd,
				rc = -EINVAL;
				break;
			}
			if (!rc)
				image_mode =
			if (!rc) {
				buf_handle.buf_lookup_type =
					BUF_LOOKUP_BY_IMG_MODE;
				buf_handle.image_mode =
				msm_isp_vfe_msg_to_img_mode(pmctl, msgid);
			}
		} else {
			image_mode = isp_output->buf.image_mode;
			buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
			buf_handle.inst_handle = isp_output->buf.inst_handle;
		}
		isp_event->isp_data.isp_msg.msg_id =
			isp_output->output_id;
		isp_event->isp_data.isp_msg.frame_id =
			isp_output->frameCounter;
		buf = isp_output->buf;
		BUG_ON(image_mode < 0);
		msm_mctl_buf_done(pmctl, image_mode,
		msm_mctl_buf_done(pmctl, &buf_handle,
			&buf, isp_output->frameCounter);
		}
		break;
+51 −1
Original line number Diff line number Diff line
@@ -882,6 +882,8 @@ static int msm_mctl_dev_close(struct file *f)
	pcam->mctl_node.dev_inst[pcam_inst->my_index] = NULL;
	v4l2_fh_del(&pcam_inst->eventHandle);
	v4l2_fh_exit(&pcam_inst->eventHandle);
	CLR_MCTLPP_INST_IDX(pcam_inst->inst_handle);
	CLR_IMG_MODE(pcam_inst->inst_handle);
	mutex_destroy(&pcam_inst->inst_lock);

	kfree(pcam_inst);
@@ -1454,7 +1456,9 @@ static int msm_mctl_v4l2_s_parm(struct file *f, void *pctx,
	struct msm_cam_v4l2_dev_inst *pcam_inst;
	pcam_inst = container_of(f->private_data,
		struct msm_cam_v4l2_dev_inst, eventHandle);
	pcam_inst->image_mode = a->parm.capture.extendedmode;
	pcam_inst->image_mode = (a->parm.capture.extendedmode & 0x7F);
	SET_IMG_MODE(pcam_inst->inst_handle, pcam_inst->image_mode);
	SET_MCTLPP_INST_IDX(pcam_inst->inst_handle, pcam_inst->my_index);
	pcam_inst->pcam->mctl_node.dev_inst_map[pcam_inst->image_mode] =
		pcam_inst;
	pcam_inst->path = msm_mctl_vidbuf_get_path(pcam_inst->image_mode);
@@ -1499,6 +1503,51 @@ static int msm_mctl_v4l2_unsubscribe_event(struct v4l2_fh *fh,
	return rc;
}

static int msm_mctl_v4l2_private_g_ctrl(struct file *f, void *pctx,
	struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
{
	int rc = -EINVAL;
	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
	struct msm_cam_v4l2_dev_inst *pcam_inst;
	pcam_inst = container_of(f->private_data,
		struct msm_cam_v4l2_dev_inst, eventHandle);

	WARN_ON(pctx != f->private_data);

	mutex_lock(&pcam->mctl_node.dev_lock);
	switch (ioctl_ptr->id) {
	case MSM_V4L2_PID_INST_HANDLE:
		COPY_TO_USER(rc, (void __user *)ioctl_ptr->ioctl_ptr,
			(void *)&pcam_inst->inst_handle, sizeof(uint32_t));
		if (rc)
			ERR_COPY_TO_USER();
		break;
	default:
		pr_err("%s Unsupported ioctl %d ", __func__, ioctl_ptr->id);
		break;
	}
	mutex_unlock(&pcam->mctl_node.dev_lock);
	return rc;
}

static long msm_mctl_v4l2_private_ioctl(struct file *file, void *fh,
	  bool valid_prio, int cmd, void *arg)
{
	int rc = -EINVAL;
	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
	D("%s: cmd %d\n", __func__, _IOC_NR(cmd));

	switch (cmd) {
	case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
		rc = msm_mctl_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
		break;
	default:
		pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
		break;
	}
	return rc;
}

/* mctl node v4l2_ioctl_ops */
static const struct v4l2_ioctl_ops g_msm_mctl_ioctl_ops = {
	.vidioc_querycap = msm_mctl_v4l2_querycap,
@@ -1538,6 +1587,7 @@ static const struct v4l2_ioctl_ops g_msm_mctl_ioctl_ops = {
	/* event subscribe/unsubscribe */
	.vidioc_subscribe_event = msm_mctl_v4l2_subscribe_event,
	.vidioc_unsubscribe_event = msm_mctl_v4l2_unsubscribe_event,
	.vidioc_default = msm_mctl_v4l2_private_ioctl,
};

int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam)
+180 −197

File changed.

Preview size limit exceeded, changes collapsed.

Loading