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

Commit 2e1910ed authored by Vikram Sharma's avatar Vikram Sharma Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: ope: Handle OPE smmu fault with pid info



Kernel apis provide information fault caused pid and mid data.
Handle the OPE smmu fault using pid and mid data. Based on the
mid data, dump only corresponding port info which caused the
fault. Pid and mid values are target dependent, these values
will be updated on the ope node dt entries.

CRs-Fixed: 2857868
Change-Id: I909f1787e71e67e5ed1d3464dfeb506418d151e4
Signed-off-by: default avatarVikram Sharma <vikramsa@codeaurora.org>
parent 168408b4
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -109,6 +109,14 @@
	 CAM_CDM_IRQ_STATUS_ERROR_OVER_FLOW_MASK | \
	 CAM_CDM_IRQ_STATUS_ERROR_AHB_BUS_MASK)


struct cam_cdm_pid_mid_data {
	int cdm_pid;
	int cdm_mid;
	int ope_cdm_pid;
	int ope_cdm_mid;
};

/* Structure to store hw version info */
struct cam_version_reg {
	uint32_t hw_version;
@@ -352,6 +360,7 @@ struct cam_cdm_common_regs {
	const struct cam_cdm_icl_regs *icl_reg;
	uint32_t spare;
	uint32_t priority_group_bit_offset;
	struct cam_cdm_pid_mid_data *cdm_pid_mid_info;
};

/**
+20 −3
Original line number Diff line number Diff line
@@ -1353,11 +1353,31 @@ static void cam_hw_cdm_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
{
	struct cam_hw_info *cdm_hw = NULL;
	struct cam_cdm *core = NULL;
	struct cam_cdm_pid_mid_data *pid_mid_info = NULL;
	int i;

	if (pf_info->token) {
		cdm_hw = (struct cam_hw_info *)pf_info->token;
		core = (struct cam_cdm *)cdm_hw->core_info;
		pid_mid_info = core->offsets->cmn_reg->cdm_pid_mid_info;
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK\n",
			(void *)pf_info->iova);

		if (pid_mid_info) {
			/*
			 * If its CDM or OPE CDM then only handle the pf for CDM
			 * else return.
			 */
			if (((pf_info->pid == pid_mid_info->cdm_pid) &&
				(pf_info->mid == pid_mid_info->cdm_mid)) ||
				((pf_info->pid == pid_mid_info->ope_cdm_pid) &&
				(pf_info->mid == pid_mid_info->ope_cdm_mid)))
				goto handle_cdm_pf;
			else
				return;
		}

handle_cdm_pf:
		set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
		mutex_lock(&cdm_hw->hw_mutex);
		for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
@@ -1371,15 +1391,12 @@ static void cam_hw_cdm_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
		for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
			mutex_unlock(&core->bl_fifo[i].fifo_lock);
		mutex_unlock(&cdm_hw->hw_mutex);
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK\n",
			(void *)pf_info->iova);
		cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
			(void *)pf_info->iova);
		clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
	} else {
		CAM_ERR(CAM_CDM, "Invalid token");
	}

}

irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
+8 −0
Original line number Diff line number Diff line
@@ -5,6 +5,13 @@

#include "cam_cdm.h"

struct cam_cdm_pid_mid_data cdm_hw_2_1_pid_mid_data = {
	.cdm_pid = 2,
	.cdm_mid = 0,
	.ope_cdm_pid = 0,
	.ope_cdm_mid = 2,
};

struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req0 = {
	.rb_offset = 0x6c,
	.rb_mask = 0x1ff,
@@ -226,6 +233,7 @@ static struct cam_cdm_common_regs cdm_hw_2_1_cmn_reg_offset = {
	.icl_reg = &cdm_2_1_icl,
	.spare = 0x3fc,
	.priority_group_bit_offset = 20,
	.cdm_pid_mid_info = &cdm_hw_2_1_pid_mid_data,
};

static struct cam_cdm_common_reg_data cdm_hw_2_1_cmn_reg_data = {
+2 −2
Original line number Diff line number Diff line
@@ -998,7 +998,7 @@ int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx)
}

int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
	struct cam_packet *packet, bool *mem_found, bool *ctx_found,
	struct cam_hw_mgr_dump_pf_data *pf_data, bool *mem_found, bool *ctx_found,
	uint32_t  *resource_type, struct cam_smmu_pf_info *pf_info)
{
	int rc = 0;
@@ -1020,7 +1020,7 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
	if (ctx->hw_mgr_intf->hw_cmd) {
		cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
		cmd_args.cmd_type = CAM_HW_MGR_CMD_DUMP_PF_INFO;
		cmd_args.u.pf_args.pf_data.packet = packet;
		cmd_args.u.pf_args.pf_data = *pf_data;
		cmd_args.u.pf_args.iova = pf_info->iova;
		cmd_args.u.pf_args.buf_info = pf_info->buf_info;
		cmd_args.u.pf_args.mem_found = mem_found;
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
	struct cam_flush_dev_cmd *cmd);
int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
	struct cam_packet *packet, bool *mem_found, bool *ctx_found,
	struct cam_hw_mgr_dump_pf_data *pf_data, bool *mem_found, bool *ctx_found,
	uint32_t  *resource_type,
	struct cam_smmu_pf_info *pf_info);
int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx);
Loading