msm: camera: reqmgr: Invoke custom device at every frame
If there is a valid request CRM will apply that request to the custom device, in scenerios during which there is no setting to be applied to a custom device at a given epoch CRM needs to invoke the custom device to program default settings for the next frame. CRs-Fixed: 2524308 Change-Id: I4701c602ab68b9f64266f03a9b200d15a808165e Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
@@ -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()
|
||||
*
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
},
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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,16 +809,27 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
pd);
|
||||
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].skip_idx,
|
||||
link->req.apply_data[pd].req_id);
|
||||
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,
|
||||
"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;
|
||||
}
|
||||
|
||||
apply_req.dev_hdl = dev->dev_hdl;
|
||||
apply_req.request_id =
|
||||
link->req.apply_data[pd].req_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;
|
||||
}
|
||||
|
||||
|
@@ -364,6 +364,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;
|
||||
@@ -397,6 +401,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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user