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

Commit 4b076f43 authored by Sagar Gore's avatar Sagar Gore Committed by Sreesudhan Ramakrish Ramkumar
Browse files

msm: camera: iommu page fault handler



Added iommu page fault handler for debugging isp page faults.
Print buffer manager configuration when page fault is detected.

Change-Id: I852626f199e9091da5a981fe3996515e781f2eda
Signed-off-by: default avatarSagar Gore <sgore@codeaurora.org>
parent e7e72293
Loading
Loading
Loading
Loading
+46 −1
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@
#else
#define CDBG(fmt, args...) do { } while (0)
#endif

static struct msm_isp_bufq *msm_isp_get_bufq(
	struct msm_isp_buf_mgr *buf_mgr,
	uint32_t bufq_handle)
@@ -855,6 +854,7 @@ static int msm_isp_init_isp_buf_mgr(
	}
	buf_mgr->client = msm_ion_client_create(-1, ctx_name);
	buf_mgr->buf_handle_cnt = 0;
	buf_mgr->pagefault_debug = 0;
	return 0;
bufq_error:
	return rc;
@@ -869,6 +869,7 @@ static int msm_isp_deinit_isp_buf_mgr(
	ion_client_destroy(buf_mgr->client);
	kfree(buf_mgr->bufq);
	buf_mgr->num_buf_q = 0;
	buf_mgr->pagefault_debug = 0;
	msm_isp_detach_ctx(buf_mgr);
	return 0;
}
@@ -896,6 +897,48 @@ int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr,
	return 0;
}

int msm_isp_buf_mgr_debug(struct msm_isp_buf_mgr *buf_mgr)
{
	struct msm_isp_buffer *bufs = NULL;
	uint32_t i = 0, j = 0, k = 0, rc = 0;
	if (!buf_mgr) {
		pr_err_ratelimited("%s: %d] NULL buf_mgr\n",
			__func__, __LINE__);
		return -EINVAL;
	}
	for (i = 0; i < BUF_MGR_NUM_BUF_Q; i++) {
		if (buf_mgr->bufq[i].bufq_handle != 0) {
			pr_err("%s:%d handle %x\n", __func__, i,
				buf_mgr->bufq[i].bufq_handle);
			pr_err("%s:%d session_id %d, stream_id %x,",
				__func__, i, buf_mgr->bufq[i].session_id,
				buf_mgr->bufq[i].stream_id);
			pr_err("num_bufs %d, handle %x, type %d\n",
				buf_mgr->bufq[i].num_bufs,
				buf_mgr->bufq[i].bufq_handle,
				buf_mgr->bufq[i].buf_type);
			for (j = 0; j < buf_mgr->bufq[i].num_bufs; j++) {
				bufs = &buf_mgr->bufq[i].bufs[j];
				pr_err("%s:%d buf_idx %d, frame_id %d,",
					__func__, j, bufs->buf_idx,
					bufs->frame_id);
				pr_err("num_planes %d, state %d\n",
					bufs->num_planes, bufs->state);
				for (k = 0; k < bufs->num_planes; k++) {
					pr_err("%s:%d paddr %x, len %lu,",
						__func__, k, (unsigned int)
						bufs->mapped_info[k].paddr,
						bufs->mapped_info[k].len);
					pr_err(" ion handle %p\n",
						bufs->mapped_info[k].handle);
				}
			}
		}
	}
	buf_mgr->pagefault_debug = 1;
	return rc;
}

static struct msm_isp_buf_ops isp_buf_ops = {
	.request_buf = msm_isp_request_bufq,
	.enqueue_buf = msm_isp_buf_enqueue,
@@ -910,6 +953,7 @@ static struct msm_isp_buf_ops isp_buf_ops = {
	.register_ctx = msm_isp_register_ctx,
	.buf_mgr_init = msm_isp_init_isp_buf_mgr,
	.buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr,
	.buf_mgr_debug = msm_isp_buf_mgr_debug,
};

int msm_isp_create_isp_buf_mgr(
@@ -940,6 +984,7 @@ int msm_isp_create_isp_buf_mgr(
	buf_mgr->vb2_ops = vb2_ops;
	buf_mgr->init_done = 1;
	buf_mgr->open_count = 0;
	buf_mgr->pagefault_debug = 0;
	return 0;
iommu_domain_error:
	return rc;
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
				MSM_ISP_BUFFER_SRC_HAL)

#define ISP_SHARE_BUF_CLIENT 2
#define BUF_MGR_NUM_BUF_Q 28

struct msm_isp_buf_mgr;

@@ -137,11 +138,13 @@ struct msm_isp_buf_ops {
	int (*buf_mgr_init) (struct msm_isp_buf_mgr *buf_mgr,
		const char *ctx_name, uint16_t num_buf_q);
	int (*buf_mgr_deinit) (struct msm_isp_buf_mgr *buf_mgr);
	int (*buf_mgr_debug) (struct msm_isp_buf_mgr *buf_mgr);
};

struct msm_isp_buf_mgr {
	int init_done;
	uint32_t open_count;
	uint32_t pagefault_debug;
	spinlock_t lock;
	uint16_t num_buf_q;
	struct msm_isp_bufq *bufq;
+30 −1
Original line number Diff line number Diff line
@@ -1263,6 +1263,31 @@ int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
	return 0;
}

static int msm_vfe_iommu_fault_handler(struct iommu_domain *domain,
	struct device *dev, unsigned long iova, int flags, void *token)
{
	struct vfe_device *vfe_dev = NULL;
	if (token) {
		vfe_dev = (struct vfe_device *)token;
		if (!vfe_dev->buf_mgr || !vfe_dev->buf_mgr->ops) {
			pr_err("%s:%d] buf_mgr %p\n", __func__,
				__LINE__, vfe_dev->buf_mgr);
			goto end;
		}
		if (!vfe_dev->buf_mgr->pagefault_debug) {
			pr_err("%s:%d] vfe_dev %p id %d\n", __func__,
				__LINE__, vfe_dev, vfe_dev->pdev->id);
			vfe_dev->buf_mgr->ops->buf_mgr_debug(vfe_dev->buf_mgr);
		}
	} else {
		ISP_DBG("%s:%d] no token received: %p\n",
			__func__, __LINE__, token);
		goto end;
	}
end:
	return -ENOSYS;
}

int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
@@ -1299,7 +1324,8 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)

	vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev);

	vfe_dev->buf_mgr->ops->buf_mgr_init(vfe_dev->buf_mgr, "msm_isp", 28);
	vfe_dev->buf_mgr->ops->buf_mgr_init(vfe_dev->buf_mgr,
		"msm_isp", BUF_MGR_NUM_BUF_Q);

	memset(&vfe_dev->axi_data, 0, sizeof(struct msm_vfe_axi_shared_data));
	memset(&vfe_dev->stats_data, 0,
@@ -1310,6 +1336,9 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
	vfe_dev->vt_enable = 0;
	vfe_dev->p_avtimer_lsw = NULL;
	vfe_dev->p_avtimer_msw = NULL;
	iommu_set_fault_handler(vfe_dev->buf_mgr->iommu_domain,
		msm_vfe_iommu_fault_handler, vfe_dev);

	mutex_unlock(&vfe_dev->core_mutex);
	mutex_unlock(&vfe_dev->realtime_mutex);
	return 0;