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

Commit 25189c24 authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Change csid stop sequence during flush" into camera-kernel.lnx.1.0

parents d6f309db 6b530bb2
Loading
Loading
Loading
Loading
+54 −1
Original line number Diff line number Diff line
@@ -824,6 +824,47 @@ static void cam_ife_hw_mgr_dump_acq_data(
	}
}

static int cam_ife_mgr_csid_change_halt_mode(struct list_head  *halt_list,
	uint32_t  base_idx, enum cam_ife_csid_halt_mode halt_mode)
{
	struct cam_ife_hw_mgr_res      *hw_mgr_res;
	struct cam_isp_resource_node   *isp_res;
	struct cam_csid_hw_halt_args    halt;
	struct cam_hw_intf             *hw_intf;
	uint32_t i;
	int rc = 0;

	list_for_each_entry(hw_mgr_res, halt_list, list) {
		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
			if (!hw_mgr_res->hw_res[i] ||
				(hw_mgr_res->hw_res[i]->res_state !=
				CAM_ISP_RESOURCE_STATE_STREAMING))
				continue;

			isp_res = hw_mgr_res->hw_res[i];
			if (isp_res->hw_intf->hw_idx != base_idx)
				continue;

			if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
				(isp_res->res_id == CAM_IFE_PIX_PATH_RES_IPP)) {
				hw_intf         = isp_res->hw_intf;
				halt.node_res   = isp_res;
				halt.halt_mode  = halt_mode;
				rc = hw_intf->hw_ops.process_cmd(
					hw_intf->hw_priv,
					CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
					&halt,
					sizeof(struct cam_csid_hw_halt_args));
				if (rc)
					CAM_ERR(CAM_ISP, "Halt update failed");
				break;
			}
		}
	}

	return rc;
}

static int cam_ife_mgr_csid_stop_hw(
	struct cam_ife_hw_mgr_ctx *ctx, struct list_head  *stop_list,
		uint32_t  base_idx, uint32_t stop_cmd)
@@ -3864,6 +3905,19 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
	 */
	if (i == ctx->num_base)
		master_base_idx = ctx->base[0].idx;

	/*Change slave mode*/
	if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY) {
		for (i = 0; i < ctx->num_base; i++) {
			if (ctx->base[i].idx == master_base_idx)
				continue;
			cam_ife_mgr_csid_change_halt_mode(
				&ctx->res_list_ife_csid,
				ctx->base[i].idx,
				CAM_CSID_HALT_MODE_INTERNAL);
		}
	}

	CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx);

	/* Stop the master CSID path first */
@@ -6954,7 +7008,6 @@ static int cam_ife_hw_mgr_handle_hw_rup(

	CAM_DBG(CAM_ISP, "RUP done for VFE:%d source %d", event_info->hw_idx,
		event_info->res_id);

	return 0;
}

+96 −0
Original line number Diff line number Diff line
@@ -2127,6 +2127,64 @@ static int cam_ife_csid_enable_pxl_path(
	return 0;
}


static void cam_ife_csid_change_pxl_halt_mode(
	struct cam_ife_csid_hw          *csid_hw,
	struct cam_isp_resource_node    *res,
	enum cam_ife_csid_halt_mode      halt_mode)
{
	uint32_t val = 0;
	const struct cam_ife_csid_reg_offset       *csid_reg;
	struct cam_hw_soc_info                     *soc_info;
	struct cam_ife_csid_path_cfg               *path_data;
	const struct cam_ife_csid_pxl_reg_offset   *pxl_reg;
	bool                                        is_ipp;

	path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
	csid_reg = csid_hw->csid_info->csid_reg;
	soc_info = &csid_hw->hw_info->soc_info;

	if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
		CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d",
			csid_hw->hw_intf->hw_idx, res->res_id);
		goto end;
	}

	if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
		res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
		CAM_ERR(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
			csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
		goto end;
	}

	if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
		is_ipp = true;
		pxl_reg = csid_reg->ipp_reg;
	} else {
		goto end;
	}

	if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
		CAM_ERR(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d",
			csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP",
			res->res_id, res->res_state);
		goto end;
	}

	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		pxl_reg->csid_pxl_irq_mask_addr);

	/* configure Halt for slave */
	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
		pxl_reg->csid_pxl_ctrl_addr);
	val &= ~0xC;
	val |= (halt_mode << 2);
	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
		pxl_reg->csid_pxl_ctrl_addr);
end:
	return;
}

static int cam_ife_csid_disable_pxl_path(
	struct cam_ife_csid_hw          *csid_hw,
	struct cam_isp_resource_node    *res,
@@ -3692,6 +3750,41 @@ int cam_ife_csid_start(void *hw_priv, void *start_args,
	return rc;
}

int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw,
		void *halt_args)
{
	struct cam_isp_resource_node         *res;
	struct cam_csid_hw_halt_args         *csid_halt;

	if (!csid_hw || !halt_args) {
		CAM_ERR(CAM_ISP, "CSID: Invalid args");
		return -EINVAL;
	}

	csid_halt = (struct cam_csid_hw_halt_args *)halt_args;

	/* Change the halt mode */
	res = csid_halt->node_res;
	CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d",
		csid_hw->hw_intf->hw_idx,
		res->res_type, res->res_id);

	switch (res->res_type) {
	case CAM_ISP_RESOURCE_PIX_PATH:
		if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
			cam_ife_csid_change_pxl_halt_mode(csid_hw, res,
				csid_halt->halt_mode);
		break;
	default:
		CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
			csid_hw->hw_intf->hw_idx,
			res->res_type);
		break;
	}

	return 0;
}

int cam_ife_csid_stop(void *hw_priv,
	void *stop_args, uint32_t arg_size)
{
@@ -4089,6 +4182,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
	case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG:
		rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args);
		break;
	case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE:
		rc = cam_ife_csid_halt(csid_hw, cmd_args);
		break;
	default:
		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
			csid_hw->hw_intf->hw_idx, cmd_type);
+27 −0
Original line number Diff line number Diff line
@@ -153,6 +153,33 @@ enum cam_ife_csid_halt_cmd {
	CAM_CSID_HALT_MAX,
};

/**
 *  enum cam_ife_csid_halt_mode_cmd - Specify the halt command type
 */
enum cam_ife_csid_halt_mode {
	CAM_CSID_HALT_MODE_INTERNAL,
	CAM_CSID_HALT_MODE_GLOBAL,
	CAM_CSID_HALT_MODE_MASTER,
	CAM_CSID_HALT_MODE_SLAVE,
	CAM_CSID_HALT_MODE_MAX,
};

/**
 * struct cam_csid_hw_halt_args
 * @halt_mode : Applicable only for PATH resources
 * 0 Internal : The CSID responds to the HALT_CMD
 * 1 Global : The CSID responds to the GLOBAL_HALT_CMD
 * 2 Master : The CSID responds to the HALT_CMD
 * 3 Slave : The CSID responds to the external halt command
 * and not the HALT_CMD register
 * @node_res : reource pointer array( ie cid or CSID)
 *
 */
struct cam_csid_hw_halt_args {
	enum cam_ife_csid_halt_mode   halt_mode;
	struct cam_isp_resource_node *node_res;
};

/**
 * struct cam_csid_hw_stop- stop all resources
 * @stop_cmd : Applicable only for PATH resources
+1 −0
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ enum cam_isp_hw_cmd_type {
	CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA,
	CAM_ISP_HW_CMD_DUMP_HW,
	CAM_ISP_HW_CMD_FE_TRIGGER_CMD,
	CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
	CAM_ISP_HW_CMD_MAX,
};