Эх сурвалжийг харах

Merge "msm: camera: isp: Add support to obtain frame index" into camera-kernel.lnx.4.0

Camera Software Integration 5 жил өмнө
parent
commit
2460a8e82a

+ 36 - 8
drivers/cam_isp/cam_isp_context.c

@@ -470,6 +470,7 @@ static void __cam_isp_ctx_send_sof_boot_timestamp(
 	req_msg.u.frame_msg.timestamp = ctx_isp->boot_timestamp;
 	req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
 	req_msg.u.frame_msg.sof_status = sof_event_status;
+	req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
 
 	CAM_DBG(CAM_ISP,
 		"request id:%lld frame number:%lld boot time stamp:0x%llx",
@@ -497,6 +498,7 @@ static void __cam_isp_ctx_send_sof_timestamp(
 	req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val;
 	req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
 	req_msg.u.frame_msg.sof_status = sof_event_status;
+	req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
 
 	CAM_DBG(CAM_ISP,
 		"request id:%lld frame number:%lld SOF time stamp:0x%llx",
@@ -863,11 +865,20 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
 	struct cam_isp_context *ctx_isp, void *evt_data)
 {
 	int rc = 0;
+	uint64_t  request_id  = 0;
 	struct cam_req_mgr_trigger_notify  notify;
 	struct cam_context *ctx = ctx_isp->base;
 	struct cam_ctx_request  *req;
 	struct cam_isp_ctx_req  *req_isp;
-	uint64_t  request_id  = 0;
+	struct cam_isp_hw_epoch_event_data *epoch_done_event_data =
+			(struct cam_isp_hw_epoch_event_data *)evt_data;
+
+	if (!evt_data) {
+		CAM_ERR(CAM_ISP, "invalid event data");
+		return -EINVAL;
+	}
+
+	ctx_isp->frame_id_meta = epoch_done_event_data->frame_id_meta;
 
 	/*
 	 * notify reqmgr with sof signal. Note, due to scheduling delay
@@ -1082,11 +1093,19 @@ end:
 static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
 	void *evt_data)
 {
-	struct cam_ctx_request    *req;
-	struct cam_isp_ctx_req    *req_isp;
-	struct cam_context        *ctx = ctx_isp->base;
-	uint64_t  request_id = 0;
+	uint64_t request_id = 0;
+	struct cam_ctx_request             *req;
+	struct cam_isp_ctx_req             *req_isp;
+	struct cam_context                 *ctx = ctx_isp->base;
+	struct cam_isp_hw_epoch_event_data *epoch_done_event_data =
+		(struct cam_isp_hw_epoch_event_data *)evt_data;
 
+	if (!evt_data) {
+		CAM_ERR(CAM_ISP, "invalid event data");
+		return -EINVAL;
+	}
+
+	ctx_isp->frame_id_meta = epoch_done_event_data->frame_id_meta;
 	if (list_empty(&ctx->wait_req_list)) {
 		/*
 		 * If no wait req in epoch, this is an error case.
@@ -1248,10 +1267,19 @@ static int __cam_isp_ctx_buf_done_in_bubble(
 static int __cam_isp_ctx_epoch_in_bubble_applied(
 	struct cam_isp_context *ctx_isp, void *evt_data)
 {
-	struct cam_ctx_request    *req;
-	struct cam_isp_ctx_req    *req_isp;
-	struct cam_context        *ctx = ctx_isp->base;
 	uint64_t  request_id = 0;
+	struct cam_ctx_request             *req;
+	struct cam_isp_ctx_req             *req_isp;
+	struct cam_context                 *ctx = ctx_isp->base;
+	struct cam_isp_hw_epoch_event_data *epoch_done_event_data =
+		(struct cam_isp_hw_epoch_event_data *)evt_data;
+
+	if (!evt_data) {
+		CAM_ERR(CAM_ISP, "invalid event data");
+		return -EINVAL;
+	}
+
+	ctx_isp->frame_id_meta = epoch_done_event_data->frame_id_meta;
 
 	/*
 	 * This means we missed the reg upd ack. So we need to

+ 21 - 18
drivers/cam_isp/cam_isp_context.h

@@ -166,6 +166,8 @@ struct cam_isp_context_req_id_info {
  *
  * @base:                      Common context object pointer
  * @frame_id:                  Frame id tracking for the isp context
+ * @frame_id_meta:             Frame id read every epoch for the ctx
+ *                             meta from the sensor
  * @substate_actiavted:        Current substate for the activated state.
  * @process_bubble:            Atomic variable to check if ctx is still
  *                             processing bubble.
@@ -195,27 +197,28 @@ struct cam_isp_context_req_id_info {
  *
  */
 struct cam_isp_context {
-	struct cam_context                   *base;
+	struct cam_context              *base;
 
-	int64_t                               frame_id;
-	enum cam_isp_ctx_activated_substate   substate_activated;
-	atomic_t                              process_bubble;
-	uint32_t                              bubble_frame_cnt;
-	struct cam_ctx_ops                   *substate_machine;
-	struct cam_isp_ctx_irq_ops           *substate_machine_irq;
+	int64_t                          frame_id;
+	uint32_t                         frame_id_meta;
+	uint32_t                         substate_activated;
+	atomic_t                         process_bubble;
+	uint32_t                         bubble_frame_cnt;
+	struct cam_ctx_ops              *substate_machine;
+	struct cam_isp_ctx_irq_ops      *substate_machine_irq;
 
-	struct cam_ctx_request                req_base[CAM_CTX_REQ_MAX];
-	struct cam_isp_ctx_req                req_isp[CAM_CTX_REQ_MAX];
+	struct cam_ctx_request           req_base[CAM_CTX_REQ_MAX];
+	struct cam_isp_ctx_req           req_isp[CAM_CTX_REQ_MAX];
 
-	void                                 *hw_ctx;
-	uint64_t                              sof_timestamp_val;
-	uint64_t                              boot_timestamp;
-	int32_t                               active_req_cnt;
-	int64_t                               reported_req_id;
-	uint32_t                              subscribe_event;
-	int64_t                               last_applied_req_id;
-	atomic64_t                            state_monitor_head;
-	struct cam_isp_context_state_monitor  cam_isp_ctx_state_monitor[
+	void                            *hw_ctx;
+	uint64_t                         sof_timestamp_val;
+	uint64_t                         boot_timestamp;
+	int32_t                          active_req_cnt;
+	int64_t                          reported_req_id;
+	uint32_t                         subscribe_event;
+	int64_t                          last_applied_req_id;
+	atomic64_t                       state_monitor_head;
+	struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
 		CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
 	struct cam_isp_context_req_id_info    req_info;
 	bool                                  rdi_only_context;

+ 31 - 21
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -4775,29 +4775,36 @@ static int cam_isp_blob_core_cfg_update(
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
 		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
 			clk_rate = 0;
-			if (!hw_mgr_res->hw_res[i] ||
-				hw_mgr_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)
+			if (!hw_mgr_res->hw_res[i])
 				continue;
 
-			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
-			if (hw_intf && hw_intf->hw_ops.process_cmd) {
-				vfe_core_config.node_res =
-					hw_mgr_res->hw_res[i];
-
-				memcpy(&vfe_core_config.core_config,
-					core_config,
-					sizeof(struct cam_isp_core_config));
-
-				rc = hw_intf->hw_ops.process_cmd(
-					hw_intf->hw_priv,
-					CAM_ISP_HW_CMD_CORE_CONFIG,
-					&vfe_core_config,
-					sizeof(
-					struct cam_vfe_core_config_args));
-				if (rc)
-					CAM_ERR(CAM_ISP, "Core cfg parse fail");
-			} else {
-				CAM_WARN(CAM_ISP, "NULL hw_intf!");
+			if ((hw_mgr_res->res_id ==
+				CAM_ISP_HW_VFE_IN_CAMIF) ||
+				(hw_mgr_res->res_id ==
+				CAM_ISP_HW_VFE_IN_PDLIB)) {
+				hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+				if (hw_intf && hw_intf->hw_ops.process_cmd) {
+					vfe_core_config.node_res =
+						hw_mgr_res->hw_res[i];
+
+					memcpy(&vfe_core_config.core_config,
+						core_config,
+						sizeof(
+						struct cam_isp_core_config));
+
+					rc = hw_intf->hw_ops.process_cmd(
+						hw_intf->hw_priv,
+						CAM_ISP_HW_CMD_CORE_CONFIG,
+						&vfe_core_config,
+						sizeof(
+						struct cam_vfe_core_config_args)
+						);
+					if (rc)
+						CAM_ERR(CAM_ISP,
+						"Core cfg parse fail");
+				} else {
+					CAM_WARN(CAM_ISP, "NULL hw_intf!");
+				}
 			}
 		}
 	}
@@ -6434,6 +6441,9 @@ static int cam_ife_hw_mgr_handle_hw_epoch(
 		if (!rc) {
 			if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
 				break;
+
+			epoch_done_event_data.frame_id_meta =
+				event_info->th_reg_val;
 			ife_hw_irq_epoch_cb(ife_hw_mgr_ctx->common.cb_priv,
 				CAM_ISP_HW_EVENT_EPOCH, &epoch_done_event_data);
 		}

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -170,10 +170,11 @@ struct cam_isp_hw_reg_update_event_data {
  * struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH
  *
  * @timestamp:     Time stamp for the epoch event
- *
+ * @frame_id_meta: Frame id value corresponding to this frame
  */
 struct cam_isp_hw_epoch_event_data {
 	uint64_t       timestamp;
+	uint32_t       frame_id_meta;
 };
 
 /**

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -174,6 +174,7 @@ struct cam_isp_resource_node {
  * @res_id:         Unique resource ID
  * @hw_idx:         IFE hw index
  * @err_type:       Error type if any
+ * @th_reg_val:     Any critical register value captured during th
  *
  */
 struct cam_isp_hw_event_info {
@@ -181,6 +182,7 @@ struct cam_isp_hw_event_info {
 	uint32_t                       res_id;
 	uint32_t                       hw_idx;
 	uint32_t                       err_type;
+	uint32_t                       th_reg_val;
 };
 
 /*

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h

@@ -263,11 +263,15 @@ struct cam_vfe_bw_control_args {
  * @list:                    list_head node for the payload
  * @irq_reg_val:             IRQ and Error register values, read when IRQ was
  *                           handled
+ * @th_reg_val:              Value of any critical register that needs to be
+ *                           read at th to avoid any latencies in bh processing
+ *
  * @ts:                      Timestamp
  */
 struct cam_vfe_top_irq_evt_payload {
 	struct list_head            list;
 	uint32_t                    irq_reg_val[CAM_IFE_IRQ_REGISTERS_MAX];
+	uint32_t                    th_reg_val;
 	struct cam_isp_timestamp    ts;
 };
 

+ 3 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 
@@ -77,6 +77,7 @@ static struct cam_vfe_camif_ver3_reg_data vfe_480_camif_reg_data = {
 	.error_irq_mask0                 = 0x82000200,
 	.error_irq_mask2                 = 0x30301F80,
 	.subscribe_irq_mask1             = 0x00000007,
+	.frame_id_irq_mask               = 0x400,
 	.enable_diagnostic_hw            = 0x1,
 	.pp_camif_cfg_en_shift           = 0,
 	.pp_camif_cfg_ife_out_en_shift   = 8,
@@ -101,7 +102,7 @@ static struct cam_vfe_top_ver3_reg_offset_common vfe480_top_common_reg = {
 	.ahb_cgc_ovd              = 0x00000024,
 	.noc_cgc_ovd              = 0x00000028,
 	.trigger_cdm_events       = 0x00000090,
-	.sbi_frame_idx            = 0x00000110,
+	.custom_frame_idx         = 0x00000110,
 	.dsp_status               = 0x0000007C,
 	.diag_config              = 0x00000064,
 	.diag_sensor_status_0     = 0x00000068,

+ 26 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c

@@ -507,6 +507,9 @@ static int cam_vfe_camif_ver3_resource_start(
 
 	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
 		rsrc_data->reg_data->sof_irq_mask;
+	if (rsrc_data->cam_common_cfg.input_mux_sel_pp & 0x3)
+		irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS0] =
+			rsrc_data->reg_data->frame_id_irq_mask;
 
 	if (!rsrc_data->sof_irq_handle) {
 		rsrc_data->sof_irq_handle = cam_irq_controller_subscribe_irq(
@@ -1191,10 +1194,21 @@ static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id,
 	}
 
 	cam_isp_hw_get_timestamp(&evt_payload->ts);
+	evt_payload->th_reg_val = 0;
 
 	for (i = 0; i < th_payload->num_registers; i++)
 		evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
 
+	/* Read frame_id meta at every epoch if custom hw is enabled */
+	if (evt_payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS1]
+		& camif_priv->reg_data->epoch0_irq_mask) {
+		if ((camif_priv->common_reg->custom_frame_idx) &&
+			(camif_priv->cam_common_cfg.input_mux_sel_pp & 0x3))
+			evt_payload->th_reg_val = cam_io_r_mb(
+			camif_priv->mem_base +
+			camif_priv->common_reg->custom_frame_idx);
+	}
+
 	th_payload->evt_payload_priv = evt_payload;
 
 	CAM_DBG(CAM_ISP, "Exit");
@@ -1210,6 +1224,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 	struct cam_vfe_top_irq_evt_payload *payload;
 	struct cam_isp_hw_event_info evt_info;
 	uint32_t irq_status[CAM_IFE_IRQ_REGISTERS_MAX] = {0};
+	uint32_t val = 0;
 	int i = 0;
 
 	if (!handler_priv || !evt_payload_priv) {
@@ -1229,6 +1244,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 	evt_info.hw_idx   = camif_node->hw_intf->hw_idx;
 	evt_info.res_id   = camif_node->res_id;
 	evt_info.res_type = camif_node->res_type;
+	evt_info.th_reg_val = 0;
 
 	if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS1]
 		& camif_priv->reg_data->sof_irq_mask) {
@@ -1259,6 +1275,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 	if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS1]
 		& camif_priv->reg_data->epoch0_irq_mask) {
 		CAM_DBG(CAM_ISP, "VFE:%d Received EPOCH", evt_info.hw_idx);
+		evt_info.th_reg_val = payload->th_reg_val;
 
 		if (camif_priv->event_cb)
 			camif_priv->event_cb(camif_priv->priv,
@@ -1294,6 +1311,15 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 			cam_vfe_camif_ver3_reg_dump(camif_node);
 	}
 
+	if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS0]
+		& camif_priv->reg_data->frame_id_irq_mask) {
+		val = cam_io_r_mb(camif_priv->mem_base +
+			camif_priv->common_reg->custom_frame_idx);
+		CAM_DBG(CAM_ISP,
+			"VFE:%d Frame id change to: %u", evt_info.hw_idx,
+			val);
+	}
+
 	if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS2]) {
 		CAM_ERR(CAM_ISP, "VFE:%d Violation", evt_info.hw_idx);
 

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.h

@@ -53,6 +53,7 @@ struct cam_vfe_camif_ver3_reg_data {
 	uint32_t     error_irq_mask0;
 	uint32_t     error_irq_mask2;
 	uint32_t     subscribe_irq_mask1;
+	uint32_t     frame_id_irq_mask;
 
 	uint32_t     enable_diagnostic_hw;
 	uint32_t     pp_camif_cfg_en_shift;

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE_TOP_VER3_H_
@@ -41,7 +41,7 @@ struct cam_vfe_top_ver3_reg_offset_common {
 	uint32_t reg_update_cmd;
 	uint32_t trigger_cdm_events;
 	uint32_t violation_status;
-	uint32_t sbi_frame_idx;
+	uint32_t custom_frame_idx;
 	uint32_t dsp_status;
 	uint32_t diag_config;
 	uint32_t diag_sensor_status_0;