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

Commit 04cf22bc authored by Suresh Vankadara's avatar Suresh Vankadara Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Handle Dual VFE incase of event mismatch" into dev/msm-4.14-camx

parents e54bcc65 09cd87da
Loading
Loading
Loading
Loading
+49 −2
Original line number Diff line number Diff line
@@ -2984,6 +2984,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
		}
	}

	ctx->dual_ife_irq_mismatch_cnt = 0;
	/* Start IFE root node: do nothing */
	CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);

@@ -3066,6 +3067,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
	ctx->is_rdi_only_context = 0;
	ctx->cdm_handle = 0;
	ctx->cdm_ops = NULL;
	ctx->dual_ife_irq_mismatch_cnt = 0;
	atomic_set(&ctx->overflow_pending, 0);
	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
		ctx->sof_cnt[i] = 0;
@@ -4078,6 +4080,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
	}
}

static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx)
{
	struct cam_ife_hw_mgr_res        *hw_mgr_res;
	struct cam_hw_intf               *hw_intf;
	struct cam_isp_hw_get_cmd_update  cmd_update;
	int i = 0;

	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
		if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
			continue;
		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
			if (!hw_mgr_res->hw_res[i])
				continue;
			switch (hw_mgr_res->hw_res[i]->res_id) {
			case CAM_ISP_HW_VFE_IN_CAMIF:
				hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
				cmd_update.res = hw_mgr_res->hw_res[i];
				cmd_update.cmd_type =
					CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP;
				hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
					CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
					&cmd_update, sizeof(cmd_update));
				break;
			default:
				break;
			}
		}
	}
}

static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{
	int rc = 0;
@@ -4748,11 +4780,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
		(event_cnt[core_idx1] &&
		(event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) {

		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) {
			rc = -1;
			return rc;
		}

		CAM_ERR_RATE_LIMIT(CAM_ISP,
			"One of the VFE could not generate hw event %d",
			hw_event_type);
		rc = -1;
		return rc;
		if (event_cnt[core_idx0] >= 2) {
			event_cnt[core_idx0]--;
			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
		}
		if (event_cnt[core_idx1] >= 2) {
			event_cnt[core_idx1]--;
			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
		}

		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1)
			cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx);
		rc = 0;
	}

	CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d",
+37 −32
Original line number Diff line number Diff line
@@ -127,13 +127,17 @@ struct cam_ife_hw_mgr_debug {
 * @sof_cnt                     sof count value per core, used for dual VFE
 * @epoch_cnt                   epoch count value per core, used for dual VFE
 * @eof_cnt                     eof count value per core, used for dual VFE
 * @overflow_pending        flat to specify the overflow is pending for the
 *                          context
 * @is_rdi_only_context     flag to specify the context has only rdi resource
 * @overflow_pending            flat to specify the overflow is pending
 *                              for the context
 * @is_rdi_only_context         flag to specify the context has only rdi
 *                              resource
 * @config_done_complete        indicator for configuration complete
 * @init_done                   indicate whether init hw is done
 * @is_fe_enable            indicate whether fetch engine\read path is enabled
 * @is_fe_enable                indicate whether fetch engine\read path
 *                              is enabled
 * @res_bitmap                  fill resource bitmap for which rup to be set
 * @dual_ife_irq_mismatch_cnt   irq mismatch count value per core, used for
 *                              dual VFE
 */
struct cam_ife_hw_mgr_ctx {
	struct list_head                list;
@@ -171,6 +175,7 @@ struct cam_ife_hw_mgr_ctx {
	bool                            init_done;
	bool                            is_fe_enable;
	unsigned long                   res_bitmap;
	uint32_t                        dual_ife_irq_mismatch_cnt;
};

/**
+1 −0
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ enum cam_isp_hw_cmd_type {
	CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE,
	CAM_ISP_HW_CMD_FE_UPDATE_IN_RD,
	CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD,
	CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
	CAM_ISP_HW_CMD_MAX,
};

+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
	case CAM_ISP_HW_CMD_CLOCK_UPDATE:
	case CAM_ISP_HW_CMD_BW_UPDATE:
	case CAM_ISP_HW_CMD_BW_CONTROL:
	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
		rc = core_info->vfe_top->hw_ops.process_cmd(
			core_info->vfe_top->top_priv, cmd_type, cmd_args,
			arg_size);
+37 −0
Original line number Diff line number Diff line
@@ -422,6 +422,40 @@ static int cam_vfe_camif_reg_dump_bh(
	return 0;
}

static int cam_vfe_camif_irq_reg_dump(
	struct cam_isp_resource_node *camif_res)
{
	struct cam_vfe_mux_camif_data *camif_priv;
	struct cam_vfe_soc_private *soc_private;
	int rc = 0;

	if (!camif_res) {
		CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n");
		return -EINVAL;
	}

	if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
		(camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
		CAM_ERR(CAM_ISP, "Error! Invalid state\n");
		return 0;
	}

	camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv;
	soc_private = camif_priv->soc_info->soc_private;

	CAM_INFO(CAM_ISP,
		"Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
		camif_priv->hw_intf->hw_idx,
		0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c),
		0x60, cam_io_r_mb(camif_priv->mem_base + 0x60));
	CAM_INFO(CAM_ISP,
		"Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
		camif_priv->hw_intf->hw_idx,
		0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c),
		0x70, cam_io_r_mb(camif_priv->mem_base + 0x70));
	return rc;
}

static int cam_vfe_camif_resource_stop(
	struct cam_isp_resource_node        *camif_res)
{
@@ -509,6 +543,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
			(struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
		camif_priv->camif_debug = *((uint32_t *)cmd_args);
		break;
	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
		rc = cam_vfe_camif_irq_reg_dump(rsrc_node);
		break;
	default:
		CAM_ERR(CAM_ISP,
			"unsupported process command:%d", cmd_type);
Loading