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

Commit d31b2e15 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Offline reprocess mode support"

parents ab401d67 1264fab1
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
@@ -413,6 +413,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
@@ -1104,37 +1104,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
@@ -922,37 +922,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