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

Commit 298c8230 authored by Abhijit Kulkarni's avatar Abhijit Kulkarni Committed by Narendra Muppalla
Browse files

msm: sde: secure camera changes for v4l2 rotator



Add support for secure camera buffer handling in SDE rotator.
This change adds detaching the secure context when the buffer
with the secure camera flag is signaled and attaches the secure
context when going back to normal non securer-camera usecases.

Change-Id: Iaff45907e78775975fa3035404dcfd9b27e6e816
Signed-off-by: default avatarAbhijit Kulkarni <kabhijit@codeaurora.org>
parent 37d10775
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -560,6 +560,15 @@ int sde_rotator_base_init(struct sde_rot_data_type **pmdata,
		goto probe_done;
	}

	mdata->iclient = msm_ion_client_create(mdata->pdev->name);
	if (IS_ERR_OR_NULL(mdata->iclient)) {
		SDEROT_ERR("msm_ion_client_create() return error (%pK)\n",
				mdata->iclient);
		mdata->iclient = NULL;
		rc = -EFAULT;
		goto probe_done;
	}

	*pmdata = mdata;

	return 0;
+5 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ enum sde_caps_settings {
	SDE_CAPS_R1_WB,
	SDE_CAPS_R3_WB,
	SDE_CAPS_R3_1P5_DOWNSCALE,
	SDE_CAPS_SEC_ATTACH_DETACH_SMMU,
	SDE_CAPS_MAX,
};

@@ -111,6 +112,7 @@ struct sde_smmu_client {
	struct sde_module_power mp;
	struct reg_bus_client *reg_bus_clt;
	bool domain_attached;
	int domain;
};

struct sde_rot_vbif_debug_bus {
@@ -169,6 +171,9 @@ struct sde_rot_data_type {
	u32 regdump_size;

	void *sde_rot_hw;
	int sec_cam_en;

	struct ion_client *iclient;
};

int sde_rotator_base_init(struct sde_rot_data_type **pmdata,
+107 −0
Original line number Diff line number Diff line
@@ -25,6 +25,10 @@
#include <linux/msm-bus-board.h>
#include <linux/regulator/consumer.h>
#include <linux/dma-direction.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/rpm-smd.h>
#include <soc/qcom/secure_buffer.h>
#include <asm/cacheflush.h>

#include "sde_rotator_base.h"
#include "sde_rotator_core.h"
@@ -37,6 +41,18 @@
#include "sde_rotator_trace.h"
#include "sde_rotator_debug.h"


/* Rotator device id to be used in SCM call */
#define SDE_ROTATOR_DEVICE	21

/* SCM call function id to be used for switching between secure and non
 * secure context
 */
#define MEM_PROTECT_SD_CTRL_SWITCH 0x18

/* Rotator secure SID */
#define SDE_ROTATOR_SECURE_SID  0xe01

/* waiting for hw time out, 3 vsync for 30fps*/
#define ROT_HW_ACQUIRE_TIMEOUT_IN_MS 100

@@ -505,6 +521,7 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer,
		planes[i].memory_id = buffer->planes[i].fd;
		planes[i].offset = buffer->planes[i].offset;
		planes[i].buffer = buffer->planes[i].buffer;
		planes[i].handle = buffer->planes[i].handle;
	}

	ret =  sde_mdp_data_get_and_validate_size(data, planes,
@@ -513,6 +530,86 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer,
	return ret;
}

static int sde_rotator_secure_session_ctrl(struct sde_rot_entry *entry)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
	uint32_t sid_info;
	struct scm_desc desc;
	unsigned int resp = 0;
	int ret = 0;

	if (test_bit(SDE_CAPS_SEC_ATTACH_DETACH_SMMU,
		mdata->sde_caps_map)) {
		sid_info = SDE_ROTATOR_SECURE_SID;
		desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL);
		desc.args[0] = SDE_ROTATOR_DEVICE;
		desc.args[1] = SCM_BUFFER_PHYS(&sid_info);
		desc.args[2] = sizeof(uint32_t);

		if (!mdata->sec_cam_en &&
			(entry->item.flags & SDE_ROTATION_SECURE_CAMERA)) {
			/*
			 * Enable secure camera operation
			 * Send SCM call to hypervisor to switch the
			 * secure_vmid to secure context
			 */
			desc.args[3] = VMID_CP_CAMERA_PREVIEW;

			mdata->sec_cam_en = 1;
			sde_smmu_secure_ctrl(0);

			dmac_flush_range(&sid_info, &sid_info + 1);
			ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
					MEM_PROTECT_SD_CTRL_SWITCH), &desc);
			resp = desc.ret[0];
			if (ret) {
				SDEROT_ERR("scm_call(1) ret=%d, resp=%x\n",
					ret, resp);
				/* failure, attach smmu */
				mdata->sec_cam_en = 0;
				sde_smmu_secure_ctrl(1);
				return -EINVAL;
			}

			SDEROT_DBG("scm_call(1) ret=%d, resp=%x",
				ret, resp);
			SDEROT_EVTLOG(1, entry->item.flags,
					entry->src_buf.p[0].addr,
					entry->dst_buf.p[0].addr);
		} else if (mdata->sec_cam_en && !(entry->item.flags &
				SDE_ROTATION_SECURE_CAMERA)) {
			/*
			 * Disable secure camera operation
			 * Send SCM call to hypervisor to switch the
			 * secure_vmid to non-secure context
			 */
			desc.args[3] = VMID_CP_PIXEL;
			mdata->sec_cam_en = 0;

			dmac_flush_range(&sid_info, &sid_info + 1);
			ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
				MEM_PROTECT_SD_CTRL_SWITCH), &desc);
			resp = desc.ret[0];

			SDEROT_DBG("scm_call(0): ret=%d, resp=%x",
				ret, resp);

			/* force smmu to reattach */
			sde_smmu_secure_ctrl(1);
			SDEROT_EVTLOG(0, entry->item.flags,
					entry->src_buf.p[0].addr,
					entry->dst_buf.p[0].addr);
		}
	} else {
		return 0;
	}
	if (ret)
		return ret;

	return resp;
}


static int sde_rotator_map_and_check_data(struct sde_rot_entry *entry)
{
	int ret;
@@ -531,6 +628,13 @@ static int sde_rotator_map_and_check_data(struct sde_rot_entry *entry)
	if (IS_ERR_VALUE(ret))
		return ret;

	ret = sde_rotator_secure_session_ctrl(entry);
	if (ret) {
		SDEROT_ERR("failed secure session enabling/disabling %d\n",
			ret);
		goto end;
	}

	/* if error during map, the caller will release the data */
	ret = sde_mdp_data_map(&entry->src_buf, true, DMA_TO_DEVICE);
	if (ret) {
@@ -642,6 +746,9 @@ static int sde_rotator_import_data(struct sde_rot_mgr *mgr,
	if (entry->item.flags & SDE_ROTATION_EXT_DMA_BUF)
		flag |= SDE_ROT_EXT_DMA_BUF;

	if (entry->item.flags & SDE_ROTATION_SECURE_CAMERA)
		flag |= SDE_SECURE_CAMERA_SESSION;

	ret = sde_rotator_import_buffer(input, &entry->src_buf, flag,
				&mgr->pdev->dev, true);
	if (ret) {
+3 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@
/* use client provided dma buf instead of ion fd */
#define SDE_ROTATION_EXT_DMA_BUF	0x20000

/* secure camera operation*/
#define SDE_ROTATION_SECURE_CAMERA	0x40000

/**********************************************************************
 * configuration structures
 **********************************************************************/
+47 −10
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ static uint32_t sde_rotator_get_flags_from_ctx(struct sde_rotator_ctx *ctx)
		ret_flags ^= SDE_ROTATION_FLIP_UD;
	if (ctx->secure)
		ret_flags |= SDE_ROTATION_SECURE;
	if (ctx->secure_camera)
		ret_flags |= SDE_ROTATION_SECURE_CAMERA;
	if (ctx->format_out.fmt.pix.field == V4L2_FIELD_INTERLACED &&
			ctx->format_cap.fmt.pix.field == V4L2_FIELD_NONE)
		ret_flags |= SDE_ROTATION_DEINTERLACE;
@@ -510,28 +512,45 @@ static void *sde_rotator_get_userptr(void *alloc_ctx,
	struct sde_rotator_ctx *ctx = alloc_ctx;
	struct sde_rotator_device *rot_dev = ctx->rot_dev;
	struct sde_rotator_buf_handle *buf;
	struct ion_client *iclient = rot_dev->mdata->iclient;

	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
	if (!buf)
		return ERR_PTR(-ENOMEM);

	buf->fd = vaddr;
	buf->secure = ctx->secure;
	buf->secure = ctx->secure || ctx->secure_camera;
	buf->ctx = ctx;
	buf->rot_dev = rot_dev;
	if (ctx->secure_camera) {
		buf->handle = ion_import_dma_buf(iclient,
				buf->fd);
		if (IS_ERR_OR_NULL(buf->handle)) {
			SDEDEV_ERR(rot_dev->dev,
				"fail get ion_handler fd:%d r:%ld\n",
				buf->fd, PTR_ERR(buf->buffer));
			goto error_buf_get;
		}
		SDEDEV_DBG(rot_dev->dev,
				"get ion_handle s:%d fd:%d buf:%pad\n",
				buf->ctx->session_id,
				buf->fd, &buf->handle);
	} else {
		buf->buffer = dma_buf_get(buf->fd);

		if (IS_ERR_OR_NULL(buf->buffer)) {
		SDEDEV_ERR(rot_dev->dev, "fail get dmabuf fd:%d r:%ld\n",
			SDEDEV_ERR(rot_dev->dev,
				"fail get dmabuf fd:%d r:%ld\n",
				buf->fd, PTR_ERR(buf->buffer));
		goto error_dma_buf_get;
			goto error_buf_get;
		}

	SDEDEV_DBG(rot_dev->dev, "get dmabuf s:%d fd:%d buf:%pad\n",
		SDEDEV_DBG(rot_dev->dev,
				"get dmabuf s:%d fd:%d buf:%pad\n",
				buf->ctx->session_id,
				buf->fd, &buf->buffer);
	}

	return buf;
error_dma_buf_get:
error_buf_get:
	kfree(buf);
	return ERR_PTR(-ENOMEM);
}
@@ -618,6 +637,9 @@ static int sde_rotator_s_ctrl(struct v4l2_ctrl *ctrl)
		ret = sde_rotator_s_ctx_ctrl(ctx, &ctx->secure, ctrl);
		break;

	case V4L2_CID_SDE_ROTATOR_SECURE_CAMERA:
		ret = sde_rotator_s_ctx_ctrl(ctx, &ctx->secure_camera, ctrl);
		break;
	default:
		v4l2_warn(&rot_dev->v4l2_dev, "invalid control %d\n", ctrl->id);
		ret = -EINVAL;
@@ -648,6 +670,17 @@ static const struct v4l2_ctrl_config sde_rotator_ctrl_secure = {
	.step = 1,
};

static const struct v4l2_ctrl_config sde_rotator_ctrl_secure_camera = {
	.ops = &sde_rotator_ctrl_ops,
	.id = V4L2_CID_SDE_ROTATOR_SECURE_CAMERA,
	.name = "Secure Camera content",
	.type = V4L2_CTRL_TYPE_INTEGER,
	.def = 0,
	.min = 0,
	.max = 1,
	.step = 1,
};

/*
 * sde_rotator_ctx_show - show context state.
 */
@@ -924,6 +957,8 @@ static int sde_rotator_open(struct file *file)
			&sde_rotator_ctrl_ops, V4L2_CID_ROTATE, 0, 270, 90, 0);
	v4l2_ctrl_new_custom(ctrl_handler,
			&sde_rotator_ctrl_secure, NULL);
	v4l2_ctrl_new_custom(ctrl_handler,
			&sde_rotator_ctrl_secure_camera, NULL);
	if (ctrl_handler->error) {
		ret = ctrl_handler->error;
		v4l2_ctrl_handler_free(ctrl_handler);
@@ -2010,11 +2045,13 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx,
	sde_rotator_get_item_from_ctx(ctx, &item);
	item.flags |= SDE_ROTATION_EXT_DMA_BUF;
	item.input.planes[0].buffer = src_handle->buffer;
	item.input.planes[0].handle = src_handle->handle;
	item.input.planes[0].offset = src_handle->addr;
	item.input.planes[0].stride = ctx->format_out.fmt.pix.bytesperline;
	item.input.plane_count = 1;
	item.input.fence = NULL;
	item.output.planes[0].buffer = dst_handle->buffer;
	item.output.planes[0].handle = dst_handle->handle;
	item.output.planes[0].offset = dst_handle->addr;
	item.output.planes[0].stride = ctx->format_cap.fmt.pix.bytesperline;
	item.output.plane_count = 1;
Loading