Explorar el Código

msm: camera: isp: Resume HW only when getting one valid req

Variable fps usecase needs to get valid req with init packet
flag after flush, this change adds a flag to detect if we
get a valid req before resuming HW. This change also stops
the sensors during flush if useland already request to stop
dev.

CRs-Fixed: 3256139
Change-Id: Ieabd327a3b5cf380ca60548c85714c96635a272d
Signed-off-by: Depeng Shao <[email protected]>
Depeng Shao hace 2 años
padre
commit
48d9123083

+ 19 - 0
drivers/cam_isp/cam_isp_context.c

@@ -5958,6 +5958,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
 	ctx_isp->rdi_only_context = false;
 	ctx_isp->req_info.last_bufdone_req_id = 0;
 	ctx_isp->v4l2_event_sub_ids = 0;
+	ctx_isp->resume_hw_in_flushed = false;
 
 	atomic64_set(&ctx_isp->state_monitor_head, -1);
 	for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++)
@@ -6116,6 +6117,11 @@ static int __cam_isp_ctx_config_dev_in_top_state(
 			if (rc)
 				CAM_ERR(CAM_ISP, "Enqueue INIT pkt failed");
 			ctx_isp->init_received = true;
+
+			if ((ctx_isp->vfps_aux_context) && (req->request_id > 0))
+				ctx_isp->resume_hw_in_flushed = true;
+			else
+				ctx_isp->resume_hw_in_flushed = false;
 		} else {
 			rc = -EINVAL;
 			CAM_ERR(CAM_ISP, "Recevied INIT pkt in wrong state:%d",
@@ -6882,6 +6888,19 @@ static int __cam_isp_ctx_config_dev_in_flushed(struct cam_context *ctx,
 		goto end;
 	}
 
+	CAM_DBG(CAM_ISP, "vfps_ctx:%s resume_hw_in_flushed:%d ctx:%d",
+		CAM_BOOL_TO_YESNO(ctx_isp->vfps_aux_context),
+		ctx_isp->resume_hw_in_flushed,
+		ctx->ctx_id);
+
+	if (ctx_isp->vfps_aux_context) {
+		/* Resume the HW only when we get first valid req */
+		if (!ctx_isp->resume_hw_in_flushed)
+			goto end;
+		else
+			ctx_isp->resume_hw_in_flushed = false;
+	}
+
 	hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
 	hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
 	isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_RESUME_HW;

+ 2 - 0
drivers/cam_isp/cam_isp_context.h

@@ -271,6 +271,7 @@ struct cam_isp_context_event_record {
  *                             true, if context is rdi only context
  * @offline_context:           Indicate whether context is for offline IFE
  * @vfps_aux_context:          Indicate whether context is for VFPS aux link
+ * @resume_hw_in_flushed:      Indicate whether resume hw in flushed state in vfps case
  * @hw_acquired:               Indicate whether HW resources are acquired
  * @init_received:             Indicate whether init config packet is received
  * @split_acquire:             Indicate whether a separate acquire is expected
@@ -327,6 +328,7 @@ struct cam_isp_context {
 	bool                                  rdi_only_context;
 	bool                                  offline_context;
 	bool                                  vfps_aux_context;
+	bool                                  resume_hw_in_flushed;
 	bool                                  hw_acquired;
 	bool                                  init_received;
 	bool                                  split_acquire;

+ 28 - 6
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -1168,7 +1168,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 
 		s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE;
 		s_ctrl->last_flush_req = 0;
-		s_ctrl->is_flushed = false;
+		s_ctrl->is_stopped_by_user = false;
 		CAM_INFO(CAM_SENSOR,
 			"CAM_ACQUIRE_DEV Success for %s sensor_id:0x%x,sensor_slave_addr:0x%x",
 			s_ctrl->sensor_name,
@@ -1276,6 +1276,9 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 		}
 		s_ctrl->sensor_state = CAM_SENSOR_START;
 
+		if (s_ctrl->stream_off_after_eof)
+			s_ctrl->is_stopped_by_user = false;
+
 		if (s_ctrl->bridge_intf.crm_cb &&
 			s_ctrl->bridge_intf.crm_cb->notify_timer) {
 			timer.link_hdl = s_ctrl->bridge_intf.link_hdl;
@@ -1302,7 +1305,8 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 	}
 		break;
 	case CAM_STOP_DEV: {
-		if ((s_ctrl->stream_off_after_eof) && (!s_ctrl->is_flushed)) {
+		if (s_ctrl->stream_off_after_eof) {
+			s_ctrl->is_stopped_by_user = true;
 			CAM_DBG(CAM_SENSOR, "Ignore stop dev cmd for VFPS feature");
 			goto release_mutex;
 		}
@@ -1310,7 +1314,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 		rc = cam_sensor_stream_off(s_ctrl);
 		if (rc)
 			goto release_mutex;
-		s_ctrl->is_flushed = false;
 	}
 		break;
 	case CAM_CONFIG_DEV: {
@@ -1366,6 +1369,14 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 
 		if (s_ctrl->i2c_data.config_settings.is_settings_valid &&
 			(s_ctrl->i2c_data.config_settings.request_id == 0)) {
+			if (s_ctrl->sensor_state == CAM_SENSOR_START) {
+				delete_request(&s_ctrl->i2c_data.config_settings);
+				CAM_ERR(CAM_SENSOR,
+					"%s: get config setting in start state",
+					s_ctrl->sensor_name);
+					goto release_mutex;
+			}
+
 			rc = cam_sensor_apply_settings(s_ctrl, 0,
 				CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG);
 
@@ -1852,6 +1863,16 @@ int32_t cam_sensor_flush_request(struct cam_req_mgr_flush_request *flush_req)
 		s_ctrl->last_flush_req = flush_req->req_id;
 		CAM_DBG(CAM_SENSOR, "last reqest to flush is %lld",
 			flush_req->req_id);
+
+		/*
+		 * Sensor can't get EOF event during flush if we do the flush
+		 * before EOF, so we need to stream off the sensor during flush
+		 * for VFPS usecase.
+		 */
+		if (s_ctrl->stream_off_after_eof && s_ctrl->is_stopped_by_user) {
+			cam_sensor_stream_off(s_ctrl);
+			s_ctrl->is_stopped_by_user = false;
+		}
 	}
 
 	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
@@ -1904,9 +1925,6 @@ int32_t cam_sensor_flush_request(struct cam_req_mgr_flush_request *flush_req)
 			"Flush request id:%lld not found in the pending list",
 			flush_req->req_id);
 
-	if (s_ctrl->stream_off_after_eof)
-		s_ctrl->is_flushed = true;
-
 	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
 	return rc;
 }
@@ -1950,6 +1968,10 @@ int cam_sensor_process_evt(struct cam_req_mgr_link_evt_data *evt_data)
 			s_ctrl->stream_off_after_eof = true;
 		else
 			s_ctrl->stream_off_after_eof = false;
+
+		CAM_DBG(CAM_SENSOR, "sensor %s stream off after eof:%s",
+			s_ctrl->sensor_name,
+			CAM_BOOL_TO_YESNO(s_ctrl->stream_off_after_eof));
 		break;
 	default:
 		/* No handling */

+ 2 - 2
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h

@@ -107,7 +107,7 @@ struct cam_sensor_dev_res_info {
  * @sensor_name: Sensor name
  * @aon_camera_id: AON Camera ID associated with this sensor
  * @last_applied_req: Last applied request id
- * @is_flushed: Indicate if the request has been flushed
+ * @is_stopped_by_user: Indicate if sensor has been stopped by userland
  * @stream_off_after_eof: Indicates if sensor needs to stream off after eof
  */
 struct cam_sensor_ctrl_t {
@@ -140,7 +140,7 @@ struct cam_sensor_ctrl_t {
 	char                           sensor_name[CAM_SENSOR_NAME_MAX_SIZE];
 	uint8_t                        aon_camera_id;
 	int64_t                        last_applied_req;
-	bool                           is_flushed;
+	bool                           is_stopped_by_user;
 	bool                           stream_off_after_eof;
 };