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:
Karthik Anantha Ram
2019-10-21 16:13:12 -07:00
parent c4d16b525c
commit f81a46003b
9 changed files with 231 additions and 7 deletions

View File

@@ -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)
{

View File

@@ -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()
*

View File

@@ -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);

View File

@@ -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,
},

View File

@@ -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;

View File

@@ -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
*

View File

@@ -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;
}

View File

@@ -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;
};
/**

View File

@@ -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;
};
/**