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

Commit 9151be40 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge c106d6be on remote branch

Change-Id: Ibdd36bfcf9c3651e8428d6d827f856eb0d43660b
parents 09971cfc c106d6be
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1818,8 +1818,14 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
		if (notify.error == CRM_KMD_ERR_FATAL) {
			req_msg.session_hdl = ctx_isp->base->session_hdl;
			req_msg.u.err_msg.device_hdl = ctx_isp->base->dev_hdl;

			if (error_type == CAM_ISP_HW_ERROR_CSID_FATAL)
				req_msg.u.err_msg.error_type =
					CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY;
			else
				req_msg.u.err_msg.error_type =
					CAM_REQ_MGR_ERROR_TYPE_RECOVERY;

			req_msg.u.err_msg.link_hdl = ctx_isp->base->link_hdl;
			req_msg.u.err_msg.request_id = error_request_id;
			req_msg.u.err_msg.resource_size = 0x0;
+64 −3
Original line number Diff line number Diff line
@@ -1918,6 +1918,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl(
		csid_acquire.in_port = in_port;
		csid_acquire.out_port = in_port->data;
		csid_acquire.node_res = NULL;
		csid_acquire.event_cb = cam_ife_hw_mgr_event_handler;
		csid_acquire.priv = ife_ctx;
		csid_acquire.crop_enable = crop_enable;
		csid_acquire.drop_enable = false;

@@ -2046,6 +2048,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
		csid_acquire.in_port = in_port;
		csid_acquire.out_port = out_port;
		csid_acquire.node_res = NULL;
		csid_acquire.event_cb = cam_ife_hw_mgr_event_handler;
		csid_acquire.priv = ife_ctx;

		/*
		 * Enable RDI pixel drop by default. CSID will enable only for
@@ -6363,6 +6367,12 @@ static int cam_ife_hw_mgr_find_affected_ctx(
			affected_core, CAM_IFE_HW_NUM_MAX))
			continue;

		if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) {
			CAM_INFO(CAM_ISP, "CTX:%d already error reported",
				ife_hwr_mgr_ctx->ctx_index);
			continue;
		}

		atomic_set(&ife_hwr_mgr_ctx->overflow_pending, 1);
		notify_err_cb = ife_hwr_mgr_ctx->common.event_cb[event_type];

@@ -6378,8 +6388,13 @@ static int cam_ife_hw_mgr_find_affected_ctx(
		 * In the call back function corresponding ISP context
		 * will update CRM about fatal Error
		 */
		if (notify_err_cb) {
			notify_err_cb(ife_hwr_mgr_ctx->common.cb_priv,
				CAM_ISP_HW_EVENT_ERROR, error_event_data);
		} else {
			CAM_WARN(CAM_ISP, "Error call back is not set");
			goto end;
		}
	}

	/* fill the affected_core in recovery data */
@@ -6388,7 +6403,34 @@ static int cam_ife_hw_mgr_find_affected_ctx(
		CAM_DBG(CAM_ISP, "Vfe core %d is affected (%d)",
			 i, recovery_data->affected_core[i]);
	}
end:
	return 0;
}

static int cam_ife_hw_mgr_handle_csid_event(
	struct cam_isp_hw_event_info *event_info)
{
	struct cam_isp_hw_error_event_data  error_event_data = {0};
	struct cam_ife_hw_event_recovery_data     recovery_data = {0};

	/* this can be extended based on the types of error
	 * received from CSID
	 */
	switch (event_info->err_type) {
	case CAM_ISP_HW_ERROR_CSID_FATAL: {

		if (!g_ife_hw_mgr.debug_cfg.enable_csid_recovery)
			break;

		error_event_data.error_type = event_info->err_type;
		cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
			event_info->hw_idx,
			&recovery_data);
		break;
	}
	default:
		break;
	}
	return 0;
}

@@ -6408,6 +6450,13 @@ static int cam_ife_hw_mgr_handle_hw_err(
	else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT)
		error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW;

	spin_lock(&g_ife_hw_mgr.ctx_lock);
	if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) {
		rc = cam_ife_hw_mgr_handle_csid_event(event_info);
		spin_unlock(&g_ife_hw_mgr.ctx_lock);
		return rc;
	}

	core_idx = event_info->hw_idx;

	if (g_ife_hw_mgr.debug_cfg.enable_recovery)
@@ -6418,6 +6467,8 @@ static int cam_ife_hw_mgr_handle_hw_err(

	rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
		core_idx, &recovery_data);
	if (rc || !(recovery_data.no_of_context))
		goto end;

	if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION)
		recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION;
@@ -6425,7 +6476,8 @@ static int cam_ife_hw_mgr_handle_hw_err(
		recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;

	cam_ife_hw_mgr_do_error_recovery(&recovery_data);

end:
	spin_unlock(&g_ife_hw_mgr.ctx_lock);
	return rc;
}

@@ -6875,6 +6927,14 @@ static int cam_ife_hw_mgr_debug_register(void)
		goto err;
	}

	if (!debugfs_create_u32("enable_csid_recovery",
		0644,
		g_ife_hw_mgr.debug_cfg.dentry,
		&g_ife_hw_mgr.debug_cfg.enable_csid_recovery)) {
		CAM_ERR(CAM_ISP, "failed to create enable_csid_recovery");
		goto err;
	}

	if (!debugfs_create_bool("enable_req_dump",
		0644,
		g_ife_hw_mgr.debug_cfg.dentry,
@@ -6921,6 +6981,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
	memset(&g_ife_hw_mgr, 0, sizeof(g_ife_hw_mgr));

	mutex_init(&g_ife_hw_mgr.ctx_mutex);
	spin_lock_init(&g_ife_hw_mgr.ctx_lock);

	if (CAM_IFE_HW_NUM_MAX != CAM_IFE_CSID_HW_NUM_MAX) {
		CAM_ERR(CAM_ISP, "CSID num is different then IFE num");
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
 * @dentry:                    Debugfs entry
 * @csid_debug:                csid debug information
 * @enable_recovery:           enable recovery
 * @enable_csid_recovery:      enable csid recovery
 * @enable_diag_sensor_status: enable sensor diagnosis status
 * @enable_req_dump:           Enable request dump on HW errors
 * @per_req_reg_dump:          Enable per request reg dump
@@ -33,6 +34,7 @@ struct cam_ife_hw_mgr_debug {
	struct dentry  *dentry;
	uint64_t       csid_debug;
	uint32_t       enable_recovery;
	uint32_t       enable_csid_recovery;
	uint32_t       camif_debug;
	bool           enable_req_dump;
	bool           per_req_reg_dump;
@@ -148,6 +150,7 @@ struct cam_ife_hw_mgr_ctx {
 * @ife_dev_caps           ife device capability per core
 * @work q                 work queue for IFE hw manager
 * @debug_cfg              debug configuration
 * @ctx_lock               Spinlock for HW manager
 */
struct cam_ife_hw_mgr {
	struct cam_isp_hw_mgr          mgr_common;
@@ -166,6 +169,7 @@ struct cam_ife_hw_mgr {
	struct cam_vfe_hw_get_hw_cap   ife_dev_caps[CAM_IFE_HW_NUM_MAX];
	struct cam_req_mgr_core_workq *workq;
	struct cam_ife_hw_mgr_debug    debug_cfg;
	spinlock_t                     ctx_lock;
};

/**
+64 −3
Original line number Diff line number Diff line
@@ -1458,6 +1458,8 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi(
		csid_acquire.out_port = out_port;
		csid_acquire.sync_mode = CAM_ISP_HW_SYNC_NONE;
		csid_acquire.node_res = NULL;
		csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
		csid_acquire.event_cb_prv = tfe_ctx;

		if (tfe_ctx->is_tpg) {
			if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx ==
@@ -4904,6 +4906,12 @@ static int cam_tfe_hw_mgr_find_affected_ctx(
			affected_core, CAM_TFE_HW_NUM_MAX))
			continue;

		if (atomic_read(&tfe_hwr_mgr_ctx->overflow_pending)) {
			CAM_INFO(CAM_ISP, "CTX:%d already error reported",
				tfe_hwr_mgr_ctx->ctx_index);
			continue;
		}

		atomic_set(&tfe_hwr_mgr_ctx->overflow_pending, 1);
		notify_err_cb = tfe_hwr_mgr_ctx->common.event_cb[event_type];

@@ -4919,8 +4927,13 @@ static int cam_tfe_hw_mgr_find_affected_ctx(
		 * In the call back function corresponding ISP context
		 * will update CRM about fatal Error
		 */
		if (notify_err_cb) {
			notify_err_cb(tfe_hwr_mgr_ctx->common.cb_priv,
			CAM_ISP_HW_EVENT_ERROR, error_event_data);
		} else {
			CAM_WARN(CAM_ISP, "Error call back is not set");
			goto end;
		}
	}

	/* fill the affected_core in recovery data */
@@ -4929,7 +4942,34 @@ static int cam_tfe_hw_mgr_find_affected_ctx(
		CAM_DBG(CAM_ISP, "tfe core %d is affected (%d)",
			 i, recovery_data->affected_core[i]);
	}
end:
	return 0;
}

static int cam_tfe_hw_mgr_handle_csid_event(
	struct cam_isp_hw_event_info *event_info)
{
	struct cam_isp_hw_error_event_data  error_event_data = {0};
	struct cam_tfe_hw_event_recovery_data     recovery_data = {0};

	/* this can be extended based on the types of error
	 * received from CSID
	 */
	switch (event_info->err_type) {
	case CAM_ISP_HW_ERROR_CSID_FATAL: {

		if (!g_tfe_hw_mgr.debug_cfg.enable_csid_recovery)
			break;

		error_event_data.error_type = event_info->err_type;
		cam_tfe_hw_mgr_find_affected_ctx(&error_event_data,
			event_info->hw_idx,
			&recovery_data);
		break;
	}
	default:
		break;
	}
	return 0;
}

@@ -4950,6 +4990,13 @@ static int cam_tfe_hw_mgr_handle_hw_err(
	else if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT)
		error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW;

	spin_lock(&g_tfe_hw_mgr.ctx_lock);
	if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) {
		rc = cam_tfe_hw_mgr_handle_csid_event(event_info);
		spin_unlock(&g_tfe_hw_mgr.ctx_lock);
		return rc;
	}

	core_idx = event_info->hw_idx;

	if (g_tfe_hw_mgr.debug_cfg.enable_recovery)
@@ -4959,9 +5006,13 @@ static int cam_tfe_hw_mgr_handle_hw_err(

	rc = cam_tfe_hw_mgr_find_affected_ctx(&error_event_data,
		core_idx, &recovery_data);
	if (rc || !(recovery_data.no_of_context))
		goto end;

	if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT)
	if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) {
		spin_unlock(&g_tfe_hw_mgr.ctx_lock);
		return rc;
	}

	if (g_tfe_hw_mgr.debug_cfg.enable_recovery) {
		/* Trigger for recovery */
@@ -4974,7 +5025,8 @@ static int cam_tfe_hw_mgr_handle_hw_err(
		CAM_DBG(CAM_ISP, "recovery is not enabled");
		rc = 0;
	}

end:
	spin_unlock(&g_tfe_hw_mgr.ctx_lock);
	return rc;
}

@@ -5422,6 +5474,14 @@ static int cam_tfe_hw_mgr_debug_register(void)
		goto err;
	}

	if (!debugfs_create_u32("enable_csid_recovery",
		0644,
		g_tfe_hw_mgr.debug_cfg.dentry,
		&g_tfe_hw_mgr.debug_cfg.enable_csid_recovery)) {
		CAM_ERR(CAM_ISP, "failed to create enable_csid_recovery");
		goto err;
	}

	if (!debugfs_create_u32("enable_reg_dump",
		0644,
		g_tfe_hw_mgr.debug_cfg.dentry,
@@ -5469,6 +5529,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
	memset(&g_tfe_hw_mgr, 0, sizeof(g_tfe_hw_mgr));

	mutex_init(&g_tfe_hw_mgr.ctx_mutex);
	spin_lock_init(&g_tfe_hw_mgr.ctx_lock);

	if (CAM_TFE_HW_NUM_MAX != CAM_TFE_CSID_HW_NUM_MAX) {
		CAM_ERR(CAM_ISP, "CSID num is different then TFE num");
+4 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
 * @dentry:                    Debugfs entry
 * @csid_debug:                csid debug information
 * @enable_recovery:           enable recovery
 * @enable_csid_recovery:      enable csid recovery
 * @camif_debug:               enable sensor diagnosis status
 * @enable_reg_dump:           enable reg dump on error;
 * @per_req_reg_dump:          Enable per request reg dump
@@ -37,6 +38,7 @@ struct cam_tfe_hw_mgr_debug {
	struct dentry  *dentry;
	uint64_t       csid_debug;
	uint32_t       enable_recovery;
	uint32_t       enable_csid_recovery;
	uint32_t       camif_debug;
	uint32_t       enable_reg_dump;
	uint32_t       per_req_reg_dump;
@@ -152,6 +154,7 @@ struct cam_tfe_hw_mgr_ctx {
 * @tfe_dev_caps           tfe device capability per core
 * @work q                 work queue for TFE hw manager
 * @debug_cfg              debug configuration
 * @ctx_lock               Spinlock for HW manager
 */
struct cam_tfe_hw_mgr {
	struct cam_isp_hw_mgr          mgr_common;
@@ -170,6 +173,7 @@ struct cam_tfe_hw_mgr {
	struct cam_tfe_hw_get_hw_cap   tfe_dev_caps[CAM_TFE_HW_NUM_MAX];
	struct cam_req_mgr_core_workq *workq;
	struct cam_tfe_hw_mgr_debug    debug_cfg;
	spinlock_t                     ctx_lock;
};

/**
Loading