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

Commit fac2b313 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: Support for secure context bank in vfe"

parents e91e44f6 86dd265c
Loading
Loading
Loading
Loading
+163 −19
Original line number Diff line number Diff line
@@ -134,6 +134,12 @@ static int msm_isp_prepare_isp_buf(struct msm_isp_buf_mgr *buf_mgr,
	int i, rc = -1;
	struct msm_isp_buffer_mapped_info *mapped_info;
	struct buffer_cmd *buf_pending = NULL;
	int domain_num;

	if (buf_mgr->secure_enable == NON_SECURE_MODE)
		domain_num = buf_mgr->iommu_domain_num;
	else
		domain_num = buf_mgr->iommu_domain_num_secure;

	for (i = 0; i < qbuf_buf->num_planes; i++) {
		mapped_info = &buf_info->mapped_info[i];
@@ -145,8 +151,18 @@ static int msm_isp_prepare_isp_buf(struct msm_isp_buf_mgr *buf_mgr,
				__func__, mapped_info->handle);
			goto ion_map_error;
		}
		if (buf_mgr->secure_enable == SECURE_MODE) {
			pr_debug("%s: Securing the ION buffers\n", __func__);
			rc = msm_ion_secure_buffer(buf_mgr->client,
				mapped_info->handle, CAMERA_SECURE_CP_USAGE, 0);
			if (rc < 0) {
				pr_err("%s: Failed to secure ion buffers rc=%d\n",
					__func__, rc);
				goto ion_map_error;
			}
		}
		if (ion_map_iommu(buf_mgr->client, mapped_info->handle,
				buf_mgr->iommu_domain_num, 0, SZ_4K,
				domain_num, 0, SZ_4K,
				0, &(mapped_info->paddr),
				&(mapped_info->len), 0, 0) < 0) {
			rc = -EINVAL;
@@ -186,6 +202,12 @@ static void msm_isp_unprepare_v4l2_buf(
	int i;
	struct msm_isp_buffer_mapped_info *mapped_info;
	struct buffer_cmd *buf_pending = NULL;
	int domain_num;

	if (buf_mgr->secure_enable == NON_SECURE_MODE)
		domain_num = buf_mgr->iommu_domain_num;
	else
		domain_num = buf_mgr->iommu_domain_num_secure;

	for (i = 0; i < buf_info->num_planes; i++) {
		mapped_info = &buf_info->mapped_info[i];
@@ -197,7 +219,13 @@ static void msm_isp_unprepare_v4l2_buf(
			if (buf_pending->mapped_info == mapped_info) {
				ion_unmap_iommu(buf_mgr->client,
					mapped_info->handle,
					buf_mgr->iommu_domain_num, 0);
					domain_num, 0);
				if (buf_mgr->secure_enable == SECURE_MODE) {
					pr_debug("%s: Unsecuring the ION buffers\n",
						__func__);
					msm_ion_unsecure_buffer(buf_mgr->client,
						mapped_info->handle);
				}
				ion_free(buf_mgr->client, mapped_info->handle);

				list_del_init(&buf_pending->list);
@@ -792,35 +820,118 @@ static void msm_isp_release_all_bufq(
}

static void msm_isp_register_ctx(struct msm_isp_buf_mgr *buf_mgr,
	struct device **iommu_ctx, int num_iommu_ctx)
	struct device **iommu_ctx1, struct device **iommu_ctx2,
	int num_iommu_ctx, int secure_num_iommu_ctx)
{
	int i;
	buf_mgr->num_iommu_ctx = num_iommu_ctx;
	for (i = 0; i < num_iommu_ctx; i++)
		buf_mgr->iommu_ctx[i] = iommu_ctx[i];
		buf_mgr->iommu_ctx[i] = iommu_ctx1[i];

	buf_mgr->num_iommu_secure_ctx = secure_num_iommu_ctx;
	for (i = 0; i < secure_num_iommu_ctx; i++)
		buf_mgr->iommu_secure_ctx[i] = iommu_ctx2[i];
}

static int msm_isp_attach_ctx(struct msm_isp_buf_mgr *buf_mgr)
static int msm_isp_attach_ctx(struct msm_isp_buf_mgr *buf_mgr,
	struct msm_vfe_smmu_attach_cmd *cmd)
{
	int rc, i;
	if (cmd->security_mode == NON_SECURE_MODE) {
		/*non secure mode*/
		for (i = 0; i < buf_mgr->num_iommu_ctx; i++) {
		rc = iommu_attach_device(buf_mgr->iommu_domain,

			if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] == 0) {
				/* attach only once */
				rc = iommu_attach_device(
					buf_mgr->iommu_domain,
					buf_mgr->iommu_ctx[i]);
				if (rc) {
			pr_err("%s: Iommu attach error\n", __func__);
					pr_err("%s: attach error bank: %d, rc : %d\n",
						__func__, i, rc);
					return -EINVAL;
				}
			}
			buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i]++;
		}
	} else {
		/*secure mode*/
		for (i = 0; i < buf_mgr->num_iommu_secure_ctx; i++) {

			if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] == 0) {
				/* attach only once */
				rc = iommu_attach_device(
					buf_mgr->iommu_domain_secure,
					buf_mgr->iommu_secure_ctx[i]);
				if (rc) {
					pr_err("%s: attach error bank: %d, rc : %d\n",
						__func__, i, rc);
					return -EINVAL;
				}
			}
			buf_mgr->attach_ref_cnt[SECURE_MODE][i]++;
		}
	}
	buf_mgr->attach_state = MSM_ISP_BUF_MGR_ATTACH;
	return 0;
}

static void msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr)
static int msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr)
{
	int i;
	for (i = 0; i < buf_mgr->num_iommu_ctx; i++)

	if (buf_mgr->attach_state == MSM_ISP_BUF_MGR_DETACH ||
		buf_mgr->open_count)
		return 0;

	if (buf_mgr->secure_enable == NON_SECURE_MODE) {
		/*non secure mode*/
		for (i = 0; i < buf_mgr->num_iommu_ctx; i++) {
			/*Detach only if ref count is one*/
			if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] == 1) {
				iommu_detach_device(buf_mgr->iommu_domain,
					buf_mgr->iommu_ctx[i]);
			}
			if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] > 0)
				--buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i];
		}
	} else {
		/*secure mode*/
		for (i = 0; i < buf_mgr->num_iommu_secure_ctx; i++) {
			/*Detach only if ref count is one*/
			if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] == 1) {
				iommu_detach_device(
						buf_mgr->iommu_domain_secure,
						buf_mgr->iommu_secure_ctx[i]);
			}
			if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] > 0)
				--buf_mgr->attach_ref_cnt[SECURE_MODE][i];
		}
	}
	buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH;
	return 0;
}

int msm_isp_smmu_attach(struct msm_isp_buf_mgr *buf_mgr,
	void *arg)
{
	struct msm_vfe_smmu_attach_cmd *cmd = arg;
	int rc = 0;
	pr_debug("%s: cmd->security_mode : %d\n", __func__, cmd->security_mode);
	if (cmd->iommu_attach_mode == IOMMU_ATTACH) {
		buf_mgr->secure_enable = cmd->security_mode;
		rc = msm_isp_attach_ctx(buf_mgr, cmd);
		if (rc < 0) {
			pr_err("%s: smmu attach error, rc :%d\n", __func__, rc);
			goto iommu_error;
		}
	} else
		msm_isp_detach_ctx(buf_mgr);

iommu_error:
	return rc;
}


static int msm_isp_init_isp_buf_mgr(
	struct msm_isp_buf_mgr *buf_mgr,
@@ -836,7 +947,6 @@ static int msm_isp_init_isp_buf_mgr(
	}
	CDBG("%s: E\n", __func__);

	msm_isp_attach_ctx(buf_mgr);
	INIT_LIST_HEAD(&buf_mgr->buffer_q);
	buf_mgr->num_buf_q = num_buf_q;
	buf_mgr->bufq =
@@ -857,7 +967,10 @@ bufq_error:
static int msm_isp_deinit_isp_buf_mgr(
	struct msm_isp_buf_mgr *buf_mgr)
{
	if (--buf_mgr->open_count)
	if (buf_mgr->open_count > 0)
		buf_mgr->open_count--;

	if (buf_mgr->open_count)
		return 0;
	msm_isp_release_all_bufq(buf_mgr);
	ion_client_destroy(buf_mgr->client);
@@ -956,6 +1069,7 @@ int msm_isp_create_isp_buf_mgr(
	struct msm_iova_layout *iova_layout)
{
	int rc = 0;
	int i = 0, j = 0;
	if (buf_mgr->init_done)
		return rc;

@@ -973,12 +1087,42 @@ int msm_isp_create_isp_buf_mgr(
		rc = -1;
		goto iommu_domain_error;
	}

	buf_mgr->ops = &isp_buf_ops;
	buf_mgr->vb2_ops = vb2_ops;
	buf_mgr->init_done = 1;
	buf_mgr->open_count = 0;
	buf_mgr->pagefault_debug = 0;
	buf_mgr->secure_enable = NON_SECURE_MODE;
	buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH;

	for (i = 0; i < MAX_PROTECTION_MODE; i++)
		for (j = 0; j < MAX_IOMMU_CTX; j++)
			buf_mgr->attach_ref_cnt[i][j] = 0;
	return 0;
iommu_domain_error:
	return rc;
}

int msm_isp_create_secure_domain(
	struct msm_isp_buf_mgr *buf_mgr,
	struct msm_iova_layout *iova_layout)
{
	int rc = 0;
	if (buf_mgr->init_done)
		return rc;
	buf_mgr->iommu_domain_num_secure = msm_register_domain(iova_layout);
	if (buf_mgr->iommu_domain_num_secure < 0) {
		pr_err("%s: Invalid iommu domain number\n", __func__);
		rc = -1;
		goto iommu_domain_error;
	}

	buf_mgr->iommu_domain_secure = msm_get_iommu_domain(
	  buf_mgr->iommu_domain_num_secure);
	if (!buf_mgr->iommu_domain_secure) {
		pr_err("%s: Invalid iommu domain\n", __func__);
		rc = -1;
		goto iommu_domain_error;
	}
	return 0;
iommu_domain_error:
	return rc;
+25 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

#define ISP_SHARE_BUF_CLIENT 2
#define BUF_MGR_NUM_BUF_Q 28
#define MAX_IOMMU_CTX 2

struct msm_isp_buf_mgr;

@@ -51,6 +52,11 @@ enum msm_isp_buffer_flush_t {
	MSM_ISP_BUFFER_FLUSH_ALL,
};

enum msm_isp_buf_mgr_state {
	MSM_ISP_BUF_MGR_ATTACH,
	MSM_ISP_BUF_MGR_DETACH,
};

struct msm_isp_buffer_mapped_info {
	unsigned long len;
	dma_addr_t paddr;
@@ -134,7 +140,8 @@ struct msm_isp_buf_ops {
		uint32_t bufq_handle, uint32_t buf_index,
		struct timeval *tv, uint32_t frame_id);
	void (*register_ctx) (struct msm_isp_buf_mgr *buf_mgr,
		struct device **iommu_ctx, int num_iommu_ctx);
		struct device **iommu_ctx1, struct device **iommu_ctx2,
		int num_iommu_ctx1, int num_iommu_ctx2);
	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);
@@ -159,9 +166,20 @@ struct msm_isp_buf_mgr {
	int iommu_domain_num;
	struct iommu_domain *iommu_domain;

	/*Add secure domain num and domain */
	int iommu_domain_num_secure;
	struct iommu_domain *iommu_domain_secure;

	/*Add secure mode*/
	int secure_enable;

	int num_iommu_ctx;
	struct device *iommu_ctx[2];
	struct list_head buffer_q;
	int num_iommu_secure_ctx;
	struct device *iommu_secure_ctx[2];
	int attach_ref_cnt[MAX_PROTECTION_MODE][MAX_IOMMU_CTX];
	enum msm_isp_buf_mgr_state attach_state;
};

int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,
@@ -170,4 +188,10 @@ int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,
int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr,
	unsigned int cmd, void *arg);

int msm_isp_create_secure_domain(struct msm_isp_buf_mgr *buf_mgr,
	struct msm_iova_layout *iova_layout);

int msm_isp_smmu_attach(struct msm_isp_buf_mgr *buf_mgr,
	void *arg);

#endif /* _MSM_ISP_BUF_H_ */
+25 −1
Original line number Diff line number Diff line
@@ -259,8 +259,32 @@ static int vfe_probe(struct platform_device *pdev)
		kfree(vfe_dev);
		return -EINVAL;
	}
	/* create secure context banks*/
	if (vfe_dev->hw_info->num_iommu_secure_ctx) {
		/*secure vfe layout*/
		struct msm_iova_layout vfe_secure_layout = {
			.partitions = &vfe_partition,
			.npartitions = 1,
			.client_name = "vfe_secure",
			.domain_flags = 0,
			.is_secure = MSM_IOMMU_DOMAIN_SECURE,
		};
		rc = msm_isp_create_secure_domain(vfe_dev->buf_mgr,
			&vfe_secure_layout);
		if (rc < 0) {
			pr_err("%s: fail to create secure domain\n", __func__);
			msm_sd_unregister(&vfe_dev->subdev);
			kfree(vfe_dev);
			return -EINVAL;
		}
	}

	vfe_dev->buf_mgr->ops->register_ctx(vfe_dev->buf_mgr,
		&vfe_dev->iommu_ctx[0], vfe_dev->hw_info->num_iommu_ctx);
		&vfe_dev->iommu_ctx[0], &vfe_dev->iommu_secure_ctx[0],
		vfe_dev->hw_info->num_iommu_ctx,
		vfe_dev->hw_info->num_iommu_secure_ctx);

	vfe_dev->buf_mgr->init_done = 1;
	vfe_dev->vfe_open_cnt = 0;
end:
	return rc;
+4 −1
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@

#include "msm_buf_mgr.h"

#define MAX_IOMMU_CTX 2
#define MAX_NUM_WM 7
#define MAX_NUM_RDI 3
#define MAX_NUM_RDI_MASTER 3
@@ -207,6 +206,8 @@ struct msm_vfe_ops {

struct msm_vfe_hardware_info {
	int num_iommu_ctx;
	/* secure iommu ctx nums */
	int num_iommu_secure_ctx;
	int vfe_clk_idx;
	struct msm_vfe_ops vfe_ops;
	struct msm_vfe_axi_hardware_info *axi_hw_info;
@@ -414,6 +415,8 @@ struct vfe_device {
	void __iomem *vfe_vbif_base;

	struct device *iommu_ctx[MAX_IOMMU_CTX];
	/*Add secure context banks*/
	struct device *iommu_secure_ctx[MAX_IOMMU_CTX];

	struct regulator *fs_vfe;
	struct clk *vfe_clk[7];
+1 −0
Original line number Diff line number Diff line
@@ -1157,6 +1157,7 @@ static struct v4l2_subdev_internal_ops msm_vfe32_internal_ops = {

struct msm_vfe_hardware_info vfe32_hw_info = {
	.num_iommu_ctx = 2,
	.num_iommu_secure_ctx = 0,
	.vfe_clk_idx = VFE32_CLK_IDX,
	.vfe_ops = {
		.irq_ops = {
Loading