Bladeren bron

Merge "msm: camera: reqmgr: Invoke custom device at every frame" into camera-kernel.lnx.4.0

Camera Software Integration 5 jaren geleden
bovenliggende
commit
f65f27de96

+ 28 - 0
drivers/cam_core/cam_context.c

@@ -182,6 +182,34 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
 	return rc;
 }
 
+int cam_context_handle_crm_apply_default_req(
+	struct cam_context *ctx,
+	struct cam_req_mgr_apply_request *apply)
+{
+	int rc = 0;
+
+	if (!ctx->state_machine) {
+		CAM_ERR(CAM_CORE, "Context is not ready");
+		return -EINVAL;
+	}
+
+	if (!apply) {
+		CAM_ERR(CAM_CORE, "Invalid apply request payload");
+		return -EINVAL;
+	}
+
+	mutex_lock(&ctx->ctx_mutex);
+	if (ctx->state_machine[ctx->state].crm_ops.apply_default)
+		rc = ctx->state_machine[ctx->state].crm_ops.apply_default(ctx,
+			apply);
+	else
+		CAM_DBG(CAM_CORE, "No crm apply_default in dev %d, state %d",
+			ctx->dev_hdl, ctx->state);
+	mutex_unlock(&ctx->ctx_mutex);
+
+	return rc;
+}
+
 int cam_context_handle_crm_flush_req(struct cam_context *ctx,
 	struct cam_req_mgr_flush_request *flush)
 {

+ 15 - 0
drivers/cam_core/cam_context.h

@@ -121,6 +121,7 @@ struct cam_ctx_ioctl_ops {
  * @link:                  Link the context
  * @unlink:                Unlink the context
  * @apply_req:             Apply setting for the context
+ * @apply_default:         Apply default settings for the context
  * @flush_req:             Flush request to remove request ids
  * @process_evt:           Handle event notification from CRM.(optional)
  * @dump_req:              Dump information for the issue request
@@ -135,6 +136,8 @@ struct cam_ctx_crm_ops {
 			struct cam_req_mgr_core_dev_link_setup *unlink);
 	int (*apply_req)(struct cam_context *ctx,
 			struct cam_req_mgr_apply_request *apply);
+	int (*apply_default)(struct cam_context *ctx,
+			struct cam_req_mgr_apply_request *apply);
 	int (*flush_req)(struct cam_context *ctx,
 			struct cam_req_mgr_flush_request *flush);
 	int (*process_evt)(struct cam_context *ctx,
@@ -302,6 +305,18 @@ int cam_context_handle_crm_unlink(struct cam_context *ctx,
 int cam_context_handle_crm_apply_req(struct cam_context *ctx,
 		struct cam_req_mgr_apply_request *apply);
 
+/**
+ * cam_context_handle_crm_apply_default_req()
+ *
+ * @brief:        Handle apply default request command
+ *
+ * @ctx:          Object pointer for cam_context
+ * @apply:        Apply default request command payload
+ *
+ */
+int cam_context_handle_crm_apply_default_req(
+	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply);
+
 /**
  * cam_context_handle_crm_flush_req()
  *

+ 21 - 0
drivers/cam_core/cam_node.c

@@ -570,6 +570,26 @@ static int __cam_node_crm_apply_req(struct cam_req_mgr_apply_request *apply)
 	return cam_context_handle_crm_apply_req(ctx, apply);
 }
 
+static int __cam_node_crm_apply_default_req(
+	struct cam_req_mgr_apply_request *apply)
+{
+	struct cam_context *ctx = NULL;
+
+	if (!apply)
+		return -EINVAL;
+
+	ctx = (struct cam_context *) cam_get_device_priv(apply->dev_hdl);
+	if (!ctx) {
+		CAM_ERR(CAM_CORE, "Can not get context for handle %d",
+			apply->dev_hdl);
+		return -EINVAL;
+	}
+
+	trace_cam_apply_req("Node", apply->request_id);
+
+	return cam_context_handle_crm_apply_default_req(ctx, apply);
+}
+
 static int __cam_node_crm_flush_req(struct cam_req_mgr_flush_request *flush)
 {
 	struct cam_context *ctx = NULL;
@@ -683,6 +703,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
 	node->crm_node_intf.flush_req = __cam_node_crm_flush_req;
 	node->crm_node_intf.process_evt = __cam_node_crm_process_evt;
 	node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
+	node->crm_node_intf.apply_default = __cam_node_crm_apply_default_req;
 
 	mutex_init(&node->list_mutex);
 	INIT_LIST_HEAD(&node->free_ctx_list);

+ 29 - 0
drivers/cam_cust/cam_custom_context.c

@@ -162,6 +162,7 @@ static int __cam_custom_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
 	dev_info->dev_id = CAM_REQ_MGR_DEVICE_CUSTOM_HW;
 	dev_info->p_delay = 1;
 	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
+	dev_info->enable_apply_default = true;
 
 	return 0;
 }
@@ -456,6 +457,32 @@ static int __cam_custom_release_dev_in_acquired(struct cam_context *ctx,
 	return rc;
 }
 
+static int __cam_custom_ctx_apply_default_settings(
+	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
+{
+	int rc = 0;
+	struct cam_custom_context *custom_ctx =
+		(struct cam_custom_context *) ctx->ctx_priv;
+	struct cam_hw_cmd_args        hw_cmd_args;
+	struct cam_custom_hw_cmd_args custom_hw_cmd_args;
+
+	hw_cmd_args.ctxt_to_hw_map = custom_ctx->hw_ctx;
+	hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+	custom_hw_cmd_args.cmd_type =
+		CAM_CUSTOM_HW_MGR_PROG_DEFAULT_CONFIG;
+	hw_cmd_args.u.internal_args = (void *)&custom_hw_cmd_args;
+
+	rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
+			&hw_cmd_args);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM,
+			"Failed to apply default settings rc %d", rc);
+	else
+		CAM_DBG(CAM_CUSTOM, "Applied default settings rc %d", rc);
+
+	return rc;
+}
+
 static int __cam_custom_ctx_apply_req_in_activated_state(
 	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
 {
@@ -1194,6 +1221,8 @@ static struct cam_ctx_ops
 			.unlink = __cam_custom_ctx_unlink_in_activated,
 			.apply_req =
 				__cam_custom_ctx_apply_req_in_activated_state,
+			.apply_default =
+				__cam_custom_ctx_apply_default_settings,
 			.flush_req = __cam_custom_ctx_flush_req_in_top_state,
 			.process_evt = __cam_custom_ctx_process_evt,
 		},

+ 52 - 0
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c

@@ -1281,6 +1281,57 @@ static int cam_custom_hw_mgr_irq_cb(void *data,
 	return 0;
 }
 
+static int cam_custom_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
+{
+	int rc = 0;
+	struct cam_hw_cmd_args        *hw_cmd_args = cmd_args;
+	struct cam_custom_hw_cmd_args *custom_hw_cmd_args;
+	struct cam_custom_hw_mgr_ctx  *custom_ctx = NULL;
+
+	if (!hw_mgr_priv || !cmd_args) {
+		CAM_ERR(CAM_CUSTOM, "Invalid arguments");
+		return -EINVAL;
+	}
+
+	custom_ctx =
+		(struct cam_custom_hw_mgr_ctx *)
+		hw_cmd_args->ctxt_to_hw_map;
+
+	if (!custom_ctx || !custom_ctx->ctx_in_use) {
+		CAM_ERR(CAM_CUSTOM, "Fatal: Invalid context is used");
+		return -EPERM;
+	}
+
+	switch (hw_cmd_args->cmd_type) {
+	case CAM_HW_MGR_CMD_INTERNAL:
+		if (!hw_cmd_args->u.internal_args) {
+			CAM_ERR(CAM_CUSTOM, "Invalid cmd arguments");
+			return -EINVAL;
+		}
+
+		custom_hw_cmd_args = (struct cam_custom_hw_cmd_args *)
+					hw_cmd_args->u.internal_args;
+
+		switch (custom_hw_cmd_args->cmd_type) {
+		case CAM_CUSTOM_HW_MGR_PROG_DEFAULT_CONFIG:
+			CAM_DBG(CAM_CUSTOM, "configure RUP and scratch buffer");
+			/* Handle event accordingly */
+			break;
+		default:
+			CAM_ERR(CAM_CUSTOM, "Invalid HW mgr command:0x%x",
+				hw_cmd_args->cmd_type);
+			rc = -EINVAL;
+			break;
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
 int cam_custom_hw_mgr_init(struct device_node *of_node,
 	struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 {
@@ -1376,6 +1427,7 @@ int cam_custom_hw_mgr_init(struct device_node *of_node,
 	hw_mgr_intf->hw_prepare_update = cam_custom_mgr_prepare_hw_update;
 	hw_mgr_intf->hw_config = cam_custom_mgr_config_hw;
 	hw_mgr_intf->hw_reset = cam_custom_hw_mgr_reset;
+	hw_mgr_intf->hw_cmd = cam_custom_mgr_cmd;
 
 	if (iommu_hdl)
 		*iommu_hdl = g_custom_hw_mgr.img_iommu_hdl;

+ 16 - 0
drivers/cam_cust/cam_custom_hw_mgr/include/cam_custom_hw_mgr_intf.h

@@ -32,6 +32,22 @@ enum cam_custom_cmd_types {
 	CAM_CUSTOM_SUBMIT_REQ,
 };
 
+enum cam_custom_hw_mgr_cmd {
+	CAM_CUSTOM_HW_MGR_CMD_NONE,
+	CAM_CUSTOM_HW_MGR_PROG_DEFAULT_CONFIG,
+};
+
+/**
+ * struct cam_custom_hw_cmd_args - Payload for hw manager command
+ *
+ * @cmd_type               HW command type
+ * @reserved               any other required data
+ */
+struct cam_custom_hw_cmd_args {
+	uint32_t                   cmd_type;
+	uint32_t                   reserved;
+};
+
 /**
  * struct cam_custom_stop_args - hardware stop arguments
  *

+ 55 - 4
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -49,6 +49,7 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
 	link->initial_skip = true;
 	link->sof_timestamp = 0;
 	link->prev_sof_timestamp = 0;
+	link->enable_apply_default = false;
 	atomic_set(&link->eof_event_cnt, 0);
 }
 
@@ -209,6 +210,35 @@ static void __cam_req_mgr_find_dev_name(
 	}
 }
 
+/**
+ * __cam_req_mgr_apply_default()
+ *
+ * @brief : Apply default settings to all devices
+ * @link  : link on which we are applying these settings
+ *
+ */
+static void __cam_req_mgr_apply_default(
+	struct cam_req_mgr_core_link *link)
+{
+	int                                  i;
+	struct cam_req_mgr_apply_request     apply_req;
+	struct cam_req_mgr_connected_device *dev = NULL;
+
+	if (!link->enable_apply_default)
+		return;
+
+	for (i = 0; i < link->num_devs; i++) {
+		dev = &link->l_dev[i];
+		apply_req.request_id = 0;
+		apply_req.dev_hdl = dev->dev_hdl;
+		apply_req.link_hdl = link->link_hdl;
+		apply_req.trigger_point = 0;
+		apply_req.report_if_bubble = 0;
+		if (dev->ops && dev->ops->apply_default)
+			dev->ops->apply_default(&apply_req);
+	}
+}
+
 /**
  * __cam_req_mgr_notify_error_on_link()
  *
@@ -738,6 +768,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
 			rc = dev->ops->apply_req(&apply_req);
 			if (rc) {
 				*failed_dev = dev;
+				__cam_req_mgr_apply_default(link);
 				return rc;
 			}
 		}
@@ -750,6 +781,10 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
 			slot->ops.skip_next_frame) {
 			slot->ops.skip_next_frame = false;
 			slot->ops.is_applied = true;
+			CAM_DBG(CAM_REQ,
+				"SEND: link_hdl: %x pd: %d req_id %lld",
+				link->link_hdl, pd, apply_req.request_id);
+			__cam_req_mgr_apply_default(link);
 			return -EAGAIN;
 		} else if ((trigger == CAM_TRIGGER_POINT_EOF) &&
 			(slot->ops.apply_at_eof)) {
@@ -774,15 +809,26 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
 					pd);
 				continue;
 			}
+
+			if (!(dev->dev_info.trigger & trigger))
+				continue;
+
 			if (link->req.apply_data[pd].skip_idx ||
-				link->req.apply_data[pd].req_id < 0) {
-				CAM_DBG(CAM_CRM, "skip %d req_id %lld",
+				(link->req.apply_data[pd].req_id < 0)) {
+				CAM_DBG(CAM_CRM,
+					"dev %s skip %d req_id %lld",
+					dev->dev_info.name,
 					link->req.apply_data[pd].skip_idx,
 					link->req.apply_data[pd].req_id);
+				apply_req.dev_hdl = dev->dev_hdl;
+				apply_req.request_id = 0;
+				apply_req.trigger_point = 0;
+				apply_req.report_if_bubble = 0;
+				if ((link->enable_apply_default) &&
+					(dev->ops) && (dev->ops->apply_default))
+					dev->ops->apply_default(&apply_req);
 				continue;
 			}
-			if (!(dev->dev_info.trigger & trigger))
-				continue;
 
 			apply_req.dev_hdl = dev->dev_hdl;
 			apply_req.request_id =
@@ -843,6 +889,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
 			if (dev->ops && dev->ops->process_evt)
 				dev->ops->process_evt(&evt_data);
 		}
+		__cam_req_mgr_apply_default(link);
 	}
 	return rc;
 }
@@ -1534,6 +1581,7 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
 				rc = -EPERM;
 			}
 			spin_unlock_bh(&link->link_state_spin_lock);
+			__cam_req_mgr_apply_default(link);
 			goto error;
 		}
 	}
@@ -3223,6 +3271,9 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
 			if (dev->dev_info.p_delay > max_delay)
 				max_delay = dev->dev_info.p_delay;
 
+			if (dev->dev_info.enable_apply_default)
+				link->enable_apply_default = true;
+
 			subscribe_event |= (uint32_t)dev->dev_info.trigger;
 		}
 

+ 5 - 0
drivers/cam_req_mgr/cam_req_mgr_core.h

@@ -365,6 +365,10 @@ struct cam_req_mgr_connected_device {
  *                         applying the settings
  * @trigger_cnt          : trigger count value per device initiating the trigger
  * @eof_event_cnt        : Atomic variable to track the number of EOF requests
+ * @enable_apply_default : Link will apply a default settings to devices on
+ *                         frames where actual settings are not available.
+ *                         This will  account for all devices irrespective of
+ *                         pipeline delay
  */
 struct cam_req_mgr_core_link {
 	int32_t                              link_hdl;
@@ -398,6 +402,7 @@ struct cam_req_mgr_core_link {
 	bool                                 dual_trigger;
 	uint32_t    trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS];
 	atomic_t                             eof_event_cnt;
+	bool                                 enable_apply_default;
 };
 
 /**

+ 7 - 0
drivers/cam_req_mgr/cam_req_mgr_interface.h

@@ -54,6 +54,7 @@ typedef int (*cam_req_mgr_notify_stop)(struct cam_req_mgr_notify_stop *);
 typedef int (*cam_req_mgr_get_dev_info) (struct cam_req_mgr_device_info *);
 typedef int (*cam_req_mgr_link_setup)(struct cam_req_mgr_core_dev_link_setup *);
 typedef int (*cam_req_mgr_apply_req)(struct cam_req_mgr_apply_request *);
+typedef int (*cam_req_mgr_apply_default)(struct cam_req_mgr_apply_request *);
 typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *);
 typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *);
 typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *);
@@ -81,6 +82,7 @@ struct cam_req_mgr_crm_cb {
  * @get_dev_info : payload to fetch device details
  * @link_setup   : payload to establish link with device
  * @apply_req    : payload to apply request id on a device linked
+ * @apply_default: payload to trigger default apply settings
  * @flush_req    : payload to flush request
  * @process_evt  : payload to generic event
  * @dump_req     : payload to dump request
@@ -89,6 +91,7 @@ struct cam_req_mgr_kmd_ops {
 	cam_req_mgr_get_dev_info     get_dev_info;
 	cam_req_mgr_link_setup       link_setup;
 	cam_req_mgr_apply_req        apply_req;
+	cam_req_mgr_apply_default    apply_default;
 	cam_req_mgr_flush_req        flush_req;
 	cam_req_mgr_process_evt      process_evt;
 	cam_req_mgr_dump_req         dump_req;
@@ -293,6 +296,9 @@ struct cam_req_mgr_notify_stop {
  * @p_delay : delay between time settings applied and take effect
  * @trigger : Trigger point for the client
  * @trigger_on : This device provides trigger
+ * @enable_apply_default : Device requests CRM to apply default
+ *                         settings for devices on a link if actual
+ *                         settings for a given frame is not available
  */
 struct cam_req_mgr_device_info {
 	int32_t                     dev_hdl;
@@ -301,6 +307,7 @@ struct cam_req_mgr_device_info {
 	enum cam_pipeline_delay     p_delay;
 	uint32_t                    trigger;
 	bool                        trigger_on;
+	bool                        enable_apply_default;
 };
 
 /**