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

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

Merge fbb8fab1 on remote branch

Change-Id: Ia7b4995bce34926ab34554c8d7674e8ad718bd5e
parents dcebc5fc fbb8fab1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1587,7 +1587,7 @@ static int cam_fd_mgr_hw_dump(
	return rc;
hw_dump:
	cur_time = ktime_get();
	diff = ktime_us_delta(frame_req->submit_timestamp, cur_time);
	diff = ktime_us_delta(cur_time, frame_req->submit_timestamp);
	cur_ts = ktime_to_timespec64(cur_time);
	req_ts = ktime_to_timespec64(frame_req->submit_timestamp);
	if (diff < CAM_FD_RESPONSE_TIME_THRESHOLD) {
+1 −1
Original line number Diff line number Diff line
@@ -5225,7 +5225,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
	return 0;
hw_dump:
	cur_time = ktime_get();
	diff = ktime_us_delta(frm_process->submit_timestamp[i], cur_time);
	diff = ktime_us_delta(cur_time, frm_process->submit_timestamp[i]);
	cur_ts = ktime_to_timespec64(cur_time);
	req_ts = ktime_to_timespec64(frm_process->submit_timestamp[i]);

+2 −3
Original line number Diff line number Diff line
@@ -2748,9 +2748,8 @@ static int __cam_isp_ctx_dump_in_top_state(
	ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
	cur_time = ktime_get();
	diff = ktime_us_delta(
		req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY],
		cur_time);
	diff = ktime_us_delta(cur_time,
		req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY]);
	if (diff < CAM_ISP_CTX_RESPONSE_TIME_THRESHOLD) {
		CAM_INFO(CAM_ISP, "req %lld found no error",
			req->request_id);
+157 −15
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)
@@ -871,6 +912,10 @@ static int cam_ife_hw_mgr_release_hw_for_ctx(
	struct cam_ife_hw_mgr_res        *hw_mgr_res;
	struct cam_ife_hw_mgr_res        *hw_mgr_res_temp;

	/* clean up the callback function */
	ife_ctx->common.cb_priv = NULL;
	memset(ife_ctx->common.event_cb, 0, sizeof(ife_ctx->common.event_cb));

	/* ife leaf resource */
	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++)
		cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_ife_out[i]);
@@ -907,10 +952,6 @@ static int cam_ife_hw_mgr_release_hw_for_ctx(
	if (ife_ctx->res_list_ife_in.res_type != CAM_IFE_HW_MGR_RES_UNINIT)
		cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_ife_in);

	/* clean up the callback function */
	ife_ctx->common.cb_priv = NULL;
	memset(ife_ctx->common.event_cb, 0, sizeof(ife_ctx->common.event_cb));

	CAM_DBG(CAM_ISP, "release context completed ctx id:%d",
		ife_ctx->ctx_index);

@@ -1524,6 +1565,16 @@ static int cam_ife_hw_mgr_acquire_csid_hw(
			if (!ife_hw_mgr->csid_devices[i])
				continue;

			if (csid_acquire->in_port->dsp_mode) {
				rc = ife_hw_mgr->ife_devices[i]->hw_ops
					.process_cmd(
					ife_hw_mgr->ife_devices[i]->hw_priv,
					CAM_ISP_HW_CMD_QUERY_DSP_MODE,
					NULL, 0);
				if (rc)
					continue;
			}

			hw_intf = ife_hw_mgr->csid_devices[i];
			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
				csid_acquire,
@@ -1539,6 +1590,15 @@ static int cam_ife_hw_mgr_acquire_csid_hw(
		if (!ife_hw_mgr->csid_devices[i])
			continue;

		if (csid_acquire->in_port->dsp_mode) {
			rc = ife_hw_mgr->ife_devices[i]->hw_ops.process_cmd(
				ife_hw_mgr->ife_devices[i]->hw_priv,
				CAM_ISP_HW_CMD_QUERY_DSP_MODE,
				NULL, 0);
			if (rc)
				continue;
		}

		hw_intf = ife_hw_mgr->csid_devices[i];
		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
			csid_acquire,
@@ -1999,18 +2059,36 @@ static int cam_ife_hw_mgr_acquire_res_root(

static int cam_ife_mgr_check_and_update_fe_v0(
	struct cam_ife_hw_mgr_ctx         *ife_ctx,
	struct cam_isp_acquire_hw_info    *acquire_hw_info)
	struct cam_isp_acquire_hw_info    *acquire_hw_info,
	uint32_t                           acquire_info_size)
{
	int i;
	struct cam_isp_in_port_info       *in_port = NULL;
	uint32_t                           in_port_length = 0;
	uint32_t                           total_in_port_length = 0;

	if (acquire_hw_info->input_info_offset >=
		acquire_hw_info->input_info_size) {
		CAM_ERR(CAM_ISP,
			"Invalid size offset 0x%x is greater then size 0x%x",
			acquire_hw_info->input_info_offset,
			acquire_hw_info->input_info_size);
		return -EINVAL;
	}

	in_port = (struct cam_isp_in_port_info *)
		((uint8_t *)&acquire_hw_info->data +
		 acquire_hw_info->input_info_offset);
	for (i = 0; i < acquire_hw_info->num_inputs; i++) {

		if (((uint8_t *)in_port +
			sizeof(struct cam_isp_in_port_info)) >
			((uint8_t *)acquire_hw_info +
			acquire_info_size)) {
			CAM_ERR(CAM_ISP, "Invalid size");
			return -EINVAL;
		}

		if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) ||
			(in_port->num_out_res <= 0)) {
			CAM_ERR(CAM_ISP, "Invalid num output res %u",
@@ -2044,18 +2122,36 @@ static int cam_ife_mgr_check_and_update_fe_v0(

static int cam_ife_mgr_check_and_update_fe_v2(
	struct cam_ife_hw_mgr_ctx         *ife_ctx,
	struct cam_isp_acquire_hw_info    *acquire_hw_info)
	struct cam_isp_acquire_hw_info    *acquire_hw_info,
	uint32_t                           acquire_info_size)
{
	int i;
	struct cam_isp_in_port_info_v2    *in_port = NULL;
	uint32_t                           in_port_length = 0;
	uint32_t                           total_in_port_length = 0;

	if (acquire_hw_info->input_info_offset >=
		acquire_hw_info->input_info_size) {
		CAM_ERR(CAM_ISP,
			"Invalid size offset 0x%x is greater then size 0x%x",
			acquire_hw_info->input_info_offset,
			acquire_hw_info->input_info_size);
		return -EINVAL;
	}

	in_port = (struct cam_isp_in_port_info_v2 *)
		((uint8_t *)&acquire_hw_info->data +
		 acquire_hw_info->input_info_offset);
	for (i = 0; i < acquire_hw_info->num_inputs; i++) {

		if (((uint8_t *)in_port +
			sizeof(struct cam_isp_in_port_info)) >
			((uint8_t *)acquire_hw_info +
			acquire_info_size)) {
			CAM_ERR(CAM_ISP, "Invalid size");
			return -EINVAL;
		}

		if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) ||
			(in_port->num_out_res <= 0)) {
			CAM_ERR(CAM_ISP, "Invalid num output res %u",
@@ -2092,7 +2188,8 @@ static int cam_ife_mgr_check_and_update_fe_v2(

static int cam_ife_mgr_check_and_update_fe(
	struct cam_ife_hw_mgr_ctx         *ife_ctx,
	struct cam_isp_acquire_hw_info    *acquire_hw_info)
	struct cam_isp_acquire_hw_info    *acquire_hw_info,
	uint32_t                           acquire_info_size)
{
	uint32_t major_ver = 0, minor_ver = 0;

@@ -2105,10 +2202,10 @@ static int cam_ife_mgr_check_and_update_fe(
	switch (major_ver) {
	case 1:
		return cam_ife_mgr_check_and_update_fe_v0(
			ife_ctx, acquire_hw_info);
			ife_ctx, acquire_hw_info, acquire_info_size);
	case 2:
		return cam_ife_mgr_check_and_update_fe_v2(
			ife_ctx, acquire_hw_info);
			ife_ctx, acquire_hw_info, acquire_info_size);
		break;
	default:
		CAM_ERR(CAM_ISP, "Invalid ver of common info from user");
@@ -2906,7 +3003,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
	acquire_hw_info =
		(struct cam_isp_acquire_hw_info *)acquire_args->acquire_info;

	rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info);
	rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info,
		acquire_args->acquire_info_size);
	if (rc) {
		CAM_ERR(CAM_ISP, "buffer size is not enough");
		goto free_cdm;
@@ -3864,6 +3962,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 */
@@ -6819,8 +6930,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 */
@@ -6829,7 +6945,7 @@ 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;
}

@@ -6893,6 +7009,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 != 0) || !(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;
@@ -6900,8 +7018,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;
}

@@ -6914,6 +7032,11 @@ static int cam_ife_hw_mgr_handle_hw_rup(
	cam_hw_event_cb_func                     ife_hwr_irq_rup_cb;
	struct cam_isp_hw_reg_update_event_data  rup_event_data;

	if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_REG_UPDATE]) {
		CAM_ERR(CAM_ISP, "event_cb[HW_EVENT_REG_UPDATE] is null");
		return 0;
	}

	ife_hwr_irq_rup_cb =
		ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_REG_UPDATE];

@@ -6954,7 +7077,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;
}

@@ -7025,6 +7147,11 @@ static int cam_ife_hw_mgr_handle_hw_epoch(
	struct cam_isp_hw_epoch_event_data    epoch_done_event_data;
	int                                   rc = 0;

	if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EPOCH]) {
		CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_EPOCH] is null");
		return 0;
	}

	ife_hw_irq_epoch_cb =
		ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EPOCH];

@@ -7074,6 +7201,11 @@ static int cam_ife_hw_mgr_handle_hw_sof(
	struct cam_isp_hw_sof_event_data      sof_done_event_data;
	int                                   rc = 0;

	if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_SOF]) {
		CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_SOF] is null");
		return 0;
	}

	memset(&sof_done_event_data, 0, sizeof(sof_done_event_data));

	ife_hw_irq_sof_cb =
@@ -7149,6 +7281,11 @@ static int cam_ife_hw_mgr_handle_hw_eof(
	struct cam_isp_hw_eof_event_data      eof_done_event_data;
	int                                   rc = 0;

	if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF]) {
		CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_EOF] is null");
		return 0;
	}

	ife_hw_irq_eof_cb =
		ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF];

@@ -7194,6 +7331,11 @@ static int cam_ife_hw_mgr_handle_hw_buf_done(
	struct cam_isp_hw_done_event_data    buf_done_event_data = {0};
	struct cam_isp_hw_event_info        *event_info = evt_info;

	if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_DONE]) {
		CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_DONE] is null");
		return 0;
	}

	ife_hwr_irq_wm_done_cb =
		ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_DONE];

+100 −3
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,
@@ -3353,7 +3411,8 @@ int cam_ife_csid_release(void *hw_priv,
			csid_hw->ipp_path_config.measure_enabled = 0;
		else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP)
			csid_hw->ppp_path_config.measure_enabled = 0;
		else
		else if (res->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 &&
				res->res_id <= CAM_IFE_PIX_PATH_RES_RDI_3)
			csid_hw->rdi_path_config[res->res_id].measure_enabled
				= 0;
		break;
@@ -3691,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)
{
@@ -4088,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);
@@ -4514,6 +4611,8 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
			csid_hw->error_irq_count++;
		}
	}

handle_fatal_error:
	spin_unlock_irqrestore(&csid_hw->lock_state, flags);

	if (csid_hw->error_irq_count >
@@ -4522,8 +4621,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		csid_hw->error_irq_count = 0;
	}

handle_fatal_error:

	if (fatal_err_detected) {
		cam_ife_csid_halt_csi2(csid_hw);
		cam_csid_handle_hw_err_irq(csid_hw,
Loading