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

Commit 5c7dbc2f authored by Harsh Shah's avatar Harsh Shah Committed by Rajesh Sastrula
Browse files

msm: camera: isp: Enable/Disable IFE SAFE to SMMU



Enable/Disable the IFE SAFE signal to SMMU Hardware through
SCM call to Hypervisor, Enable SAFE before starting the IFE
Hardware and Disable it after stopping the IFE Hardware. This
is to work around the Hardware bug, that is incorrectly
clamping the SAFE signal externally due to wrong
power on reset values of SAFE LUTs. The SCM call needs to be
invoked to enable SAFE before starting first IFE Hardware
instance, disable SAFE to be invoked only after stoping all
the IFE HW instances, hence it is ref counted with active
context count.

Change-Id: I0889c53d0e824592d67f0207c9163f2564a80259
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
Signed-off-by: default avatarRajesh Sastrula <vrajesh@codeaurora.org>
parent 3f8372c1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/inc
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include

obj-$(CONFIG_SPECTRA_CAMERA) += hw_utils/ isp_hw/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_isp_hw_mgr.o cam_ife_hw_mgr.o
+63 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <soc/qcom/scm.h>
#include <uapi/media/cam_isp.h>
#include "cam_smmu_api.h"
#include "cam_req_mgr_workq.h"
@@ -26,11 +27,50 @@
#include "cam_cdm_intf_api.h"
#include "cam_packet_util.h"
#include "cam_debug_util.h"
#include "cam_cpas_api.h"

#define CAM_IFE_HW_ENTRIES_MAX  20

#define TZ_SVC_SMMU_PROGRAM 0x15
#define TZ_SAFE_SYSCALL_ID  0x3
#define CAM_IFE_SAFE_DISABLE 0
#define CAM_IFE_SAFE_ENABLE 1
#define SMMU_SE_IFE 0

static struct cam_ife_hw_mgr g_ife_hw_mgr;

static int cam_ife_notify_safe_lut_scm(bool safe_trigger)
{
	uint32_t camera_hw_version, rc = 0;
	struct scm_desc desc = {0};

	rc = cam_cpas_get_cpas_hw_version(&camera_hw_version);
	if (!rc) {
		switch (camera_hw_version) {
		case CAM_CPAS_TITAN_170_V100:
		case CAM_CPAS_TITAN_170_V110:
		case CAM_CPAS_TITAN_175_V100:

			desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL);
			desc.args[0] = SMMU_SE_IFE;
			desc.args[1] = safe_trigger;

			CAM_DBG(CAM_ISP, "Safe scm call %d", safe_trigger);
			if (scm_call2(SCM_SIP_FNID(TZ_SVC_SMMU_PROGRAM,
					TZ_SAFE_SYSCALL_ID), &desc)) {
				CAM_ERR(CAM_ISP,
					"scm call to Enable Safe failed");
				rc = -EINVAL;
			}
			break;
		default:
			break;
		}
	}

	return rc;
}

static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv,
	void *hw_caps_args)
{
@@ -1600,6 +1640,17 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)

	CAM_DBG(CAM_ISP, "Exit...ctx id:%d rc :%d", ctx->ctx_index, rc);

	mutex_lock(&g_ife_hw_mgr.ctx_mutex);
	if (!atomic_dec_return(&g_ife_hw_mgr.active_ctx_cnt)) {
		rc = cam_ife_notify_safe_lut_scm(CAM_IFE_SAFE_DISABLE);
		if (rc) {
			CAM_ERR(CAM_ISP,
				"SAFE SCM call failed:Check TZ/HYP dependency");
			rc = 0;
		}
	}
	mutex_unlock(&g_ife_hw_mgr.ctx_mutex);

	return rc;
}

@@ -1808,6 +1859,17 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
		}
	}

	mutex_lock(&g_ife_hw_mgr.ctx_mutex);
	if (!atomic_fetch_inc(&g_ife_hw_mgr.active_ctx_cnt)) {
		rc = cam_ife_notify_safe_lut_scm(CAM_IFE_SAFE_ENABLE);
		if (rc) {
			CAM_ERR(CAM_ISP,
				"SAFE SCM call failed:Check TZ/HYP dependency");
			rc = -1;
		}
	}
	mutex_unlock(&g_ife_hw_mgr.ctx_mutex);

	CAM_DBG(CAM_ISP, "start cdm interface");
	rc = cam_cdm_stream_on(ctx->cdm_handle);
	if (rc) {
@@ -3414,6 +3476,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf)
		g_ife_hw_mgr.mgr_common.cmd_iommu_hdl_secure = -1;
	}

	atomic_set(&g_ife_hw_mgr.active_ctx_cnt, 0);
	for (i = 0; i < CAM_CTX_MAX; i++) {
		memset(&g_ife_hw_mgr.ctx_pool[i], 0,
			sizeof(g_ife_hw_mgr.ctx_pool[i]));
+3 −2
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ struct cam_ife_hw_mgr {
	struct cam_soc_reg_map        *cdm_reg_map[CAM_IFE_HW_NUM_MAX];

	struct mutex                   ctx_mutex;
	atomic_t                       active_ctx_cnt;
	struct list_head               free_ctx_list;
	struct list_head               used_ctx_list;
	struct cam_ife_hw_mgr_ctx      ctx_pool[CAM_CTX_MAX];