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

Commit 1264fab1 authored by Sagar Gore's avatar Sagar Gore
Browse files

msm: camera: isp: Offline reprocess mode support



Adding support to map buffer in fetch engine driver on the fly.
This is needed for Offline reprocess mode of offline ISP.
Added ioctl to unmap buffer after fetch read done, which are
not part of any bufq/stream.

Change-Id: I25eb7e3fe6218b51f94a7f835393aa40eb1ad611
Signed-off-by: default avatarSagar Gore <sgore@codeaurora.org>
parent 50e0173f
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -214,6 +214,53 @@ static void msm_isp_unprepare_v4l2_buf(
	return;
}

static int msm_isp_map_buf(struct msm_isp_buf_mgr *buf_mgr,
	struct msm_isp_buffer_mapped_info *mapped_info, uint32_t fd)
{
	int rc = 0;
	int ret;

	if (!buf_mgr || !mapped_info) {
		pr_err_ratelimited("%s: %d] NULL ptr buf_mgr %p mapped_info %p\n",
			__func__, __LINE__, buf_mgr, mapped_info);
		return -EINVAL;
	}
	ret = cam_smmu_get_phy_addr(buf_mgr->iommu_hdl,
				fd,
				CAM_SMMU_MAP_RW,
				&(mapped_info->paddr),
				&(mapped_info->len));

	if (ret) {
		rc = -EINVAL;
		pr_err_ratelimited("%s: cannot map address", __func__);
		goto smmu_map_error;
	}
	CDBG("%s: addr:%lu\n",
		__func__, (unsigned long)mapped_info->paddr);

	return rc;
smmu_map_error:
	cam_smmu_put_phy_addr(buf_mgr->iommu_hdl,
			fd);
	return rc;
}

static int msm_isp_unmap_buf(struct msm_isp_buf_mgr *buf_mgr,
	uint32_t fd)
{
	if (!buf_mgr) {
		pr_err_ratelimited("%s: %d] NULL ptr buf_mgr\n",
			__func__, __LINE__);
		return -EINVAL;
	}

	cam_smmu_put_phy_addr(buf_mgr->iommu_hdl,
			fd);

	return 0;
}

static int msm_isp_buf_prepare(struct msm_isp_buf_mgr *buf_mgr,
	struct msm_isp_qbuf_info *info, struct vb2_buffer *vb2_buf)
{
@@ -1211,24 +1258,34 @@ int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr,
	switch (cmd) {
	case VIDIOC_MSM_ISP_REQUEST_BUF: {
		struct msm_isp_buf_request *buf_req = arg;

		buf_mgr->ops->request_buf(buf_mgr, buf_req);
		break;
	}
	case VIDIOC_MSM_ISP_ENQUEUE_BUF: {
		struct msm_isp_qbuf_info *qbuf_info = arg;

		buf_mgr->ops->enqueue_buf(buf_mgr, qbuf_info);
		break;
	}
	case VIDIOC_MSM_ISP_DEQUEUE_BUF: {
		struct msm_isp_qbuf_info *qbuf_info = arg;

		buf_mgr->ops->dequeue_buf(buf_mgr, qbuf_info);
		break;
	}
	case VIDIOC_MSM_ISP_RELEASE_BUF: {
		struct msm_isp_buf_request *buf_req = arg;

		buf_mgr->ops->release_buf(buf_mgr, buf_req->handle);
		break;
	}
	case VIDIOC_MSM_ISP_UNMAP_BUF: {
		struct msm_isp_unmap_buf_req *unmap_req = arg;

		buf_mgr->ops->unmap_buf(buf_mgr, unmap_req->fd);
		break;
	}
	}
	return 0;
}
@@ -1369,6 +1426,8 @@ static struct msm_isp_buf_ops isp_buf_ops = {
	.get_buf_src = msm_isp_get_buf_src,
	.get_buf = msm_isp_get_buf,
	.get_buf_by_index = msm_isp_get_buf_by_index,
	.map_buf = msm_isp_map_buf,
	.unmap_buf = msm_isp_unmap_buf,
	.put_buf = msm_isp_put_buf,
	.flush_buf = msm_isp_flush_buf,
	.buf_done = msm_isp_buf_done,
+5 −0
Original line number Diff line number Diff line
@@ -134,6 +134,11 @@ struct msm_isp_buf_ops {
		uint32_t bufq_handle, uint32_t buf_index,
		struct msm_isp_buffer **buf_info);

	int (*map_buf)(struct msm_isp_buf_mgr *buf_mgr,
		struct msm_isp_buffer_mapped_info *mapped_info, uint32_t fd);

	int (*unmap_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t fd);

	int (*put_buf)(struct msm_isp_buf_mgr *buf_mgr,
		uint32_t bufq_handle, uint32_t buf_index);

+2 −0
Original line number Diff line number Diff line
@@ -423,6 +423,8 @@ struct msm_vfe_fetch_engine_info {
	uint32_t bufq_handle;
	uint32_t buf_idx;
	uint8_t is_busy;
	uint8_t offline_mode;
	uint32_t fd;
};

enum msm_wm_ub_cfg_type {
+31 −12
Original line number Diff line number Diff line
@@ -1099,37 +1099,56 @@ static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev,
	void *arg)
{
	int rc = 0;
	uint32_t bufq_handle;
	uint32_t bufq_handle = 0;
	struct msm_isp_buffer *buf = NULL;
	struct msm_vfe_fetch_eng_start *fe_cfg = arg;
	struct msm_isp_buffer_mapped_info mapped_info;

	if (vfe_dev->fetch_engine_info.is_busy == 1) {
		pr_err("%s: fetch engine busy\n", __func__);
		return -EINVAL;
	}

	memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info));
	/* There is other option of passing buffer address from user,
	 * in such case, driver needs to map the buffer and use it*/
	bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
		vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id);
	vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
		in such case, driver needs to map the buffer and use it*/
	vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id;
	vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id;
	vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode;
	vfe_dev->fetch_engine_info.fd = fe_cfg->fd;

	if (!fe_cfg->offline_mode) {
		bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
				vfe_dev->buf_mgr, fe_cfg->session_id,
				fe_cfg->stream_id);
		vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;

		rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
			vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
		if (rc < 0 || !buf) {
			pr_err("%s: No fetch buffer rc= %d buf= %p\n",
				__func__, rc, buf);
			return -EINVAL;
		}
		mapped_info = buf->mapped_info[0];
		buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
	} else {
		rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
			&mapped_info, fe_cfg->fd);
	if (rc < 0) {
		pr_err("%s: No fetch buffer\n", __func__);
			pr_err("%s: can not map buffer\n", __func__);
		return -EINVAL;
	}

	}
	vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx;
	vfe_dev->fetch_engine_info.is_busy = 1;
	msm_camera_io_w(buf->mapped_info[0].paddr, vfe_dev->vfe_base + 0x228);

	msm_camera_io_w(mapped_info.paddr, vfe_dev->vfe_base + 0x228);

	msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C);
	msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C);
	buf->state = MSM_ISP_BUFFER_STATE_DIVERTED;

	ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id);
	return 0;
}

+26 −12
Original line number Diff line number Diff line
@@ -921,37 +921,51 @@ static int msm_vfe44_fetch_engine_start(struct vfe_device *vfe_dev,
	uint32_t bufq_handle;
	struct msm_isp_buffer *buf = NULL;
	struct msm_vfe_fetch_eng_start *fe_cfg = arg;
	struct msm_isp_buffer_mapped_info mapped_info;

	if (vfe_dev->fetch_engine_info.is_busy == 1) {
		pr_err("%s: fetch engine busy\n", __func__);
		return -EINVAL;
	}

	memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info));
	/* There is other option of passing buffer address from user,
		in such case, driver needs to map the buffer and use it*/
	bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
		vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id);
	vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
	vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id;
	vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id;
	vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode;
	vfe_dev->fetch_engine_info.fd = fe_cfg->fd;

	if (!fe_cfg->offline_mode) {
		bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
			vfe_dev->buf_mgr, fe_cfg->session_id,
			fe_cfg->stream_id);
		vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
		rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
			vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
		if (rc < 0) {
			pr_err("%s: No fetch buffer\n", __func__);
			return -EINVAL;
		}
		mapped_info = buf->mapped_info[0];
		buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
	} else {
		rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
			&mapped_info, fe_cfg->fd);
		if (rc < 0) {
			pr_err("%s: can not map buffer\n", __func__);
			return -EINVAL;
		}
	}
	vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx;
	vfe_dev->fetch_engine_info.is_busy = 1;

	msm_camera_io_w(buf->mapped_info[0].paddr, vfe_dev->vfe_base + 0x228);
	msm_camera_io_w(mapped_info.paddr, vfe_dev->vfe_base + 0x228);

	msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C);
	msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C);

	ISP_DBG("%s: Fetch Engine ready\n", __func__);
	buf->state = MSM_ISP_BUFFER_STATE_DIVERTED;

	return 0;
}

Loading