|
@@ -4274,6 +4274,16 @@ static struct cam_ctx_ops
|
|
|
},
|
|
|
};
|
|
|
|
|
|
+static void __cam_isp_ctx_free_mem_hw_entries(struct cam_context *ctx)
|
|
|
+{
|
|
|
+ kfree(ctx->out_map_entries);
|
|
|
+ kfree(ctx->in_map_entries);
|
|
|
+ kfree(ctx->hw_update_entry);
|
|
|
+ ctx->out_map_entries = NULL;
|
|
|
+ ctx->in_map_entries = NULL;
|
|
|
+ ctx->hw_update_entry = NULL;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
|
|
|
void *cmd)
|
|
|
{
|
|
@@ -4325,6 +4335,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
|
|
|
spin_lock_bh(&ctx->lock);
|
|
|
rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
|
|
|
spin_unlock_bh(&ctx->lock);
|
|
|
+ __cam_isp_ctx_free_mem_hw_entries(ctx);
|
|
|
ctx->state = CAM_CTX_ACQUIRED;
|
|
|
|
|
|
trace_cam_context_state("ISP", ctx);
|
|
@@ -4390,6 +4401,8 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
|
|
|
spin_lock_bh(&ctx->lock);
|
|
|
rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
|
|
|
spin_unlock_bh(&ctx->lock);
|
|
|
+ __cam_isp_ctx_free_mem_hw_entries(ctx);
|
|
|
+
|
|
|
ctx->state = CAM_CTX_AVAILABLE;
|
|
|
|
|
|
trace_cam_context_state("ISP", ctx);
|
|
@@ -4491,10 +4504,10 @@ static int __cam_isp_ctx_config_dev_in_top_state(
|
|
|
cfg.packet = packet;
|
|
|
cfg.remain_len = remain_len;
|
|
|
cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
|
|
|
- cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX;
|
|
|
+ cfg.max_hw_update_entries = ctx->max_hw_update_entries;
|
|
|
cfg.hw_update_entries = req_isp->cfg;
|
|
|
- cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX;
|
|
|
- cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
|
|
|
+ cfg.max_out_map_entries = ctx->max_out_map_entries;
|
|
|
+ cfg.max_in_map_entries = ctx->max_in_map_entries;
|
|
|
cfg.out_map_entries = req_isp->fence_map_out;
|
|
|
cfg.in_map_entries = req_isp->fence_map_in;
|
|
|
cfg.priv = &req_isp->hw_update_data;
|
|
@@ -4606,6 +4619,65 @@ free_req:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int __cam_isp_ctx_allocate_mem_hw_entries(struct cam_context *ctx)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ struct cam_ctx_request *req;
|
|
|
+ struct cam_ctx_request *temp_req;
|
|
|
+ struct cam_isp_ctx_req *req_isp;
|
|
|
+ size_t num_entries = 0;
|
|
|
+
|
|
|
+ num_entries = ctx->max_hw_update_entries * CAM_ISP_CTX_REQ_MAX;
|
|
|
+ ctx->hw_update_entry = kcalloc(num_entries,
|
|
|
+ sizeof(struct cam_hw_update_entry),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!ctx->hw_update_entry) {
|
|
|
+ CAM_ERR(CAM_CTXT, "%s[%d] no memory", ctx->dev_name, ctx->ctx_id);
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ num_entries = ctx->max_in_map_entries * CAM_ISP_CTX_REQ_MAX;
|
|
|
+ ctx->in_map_entries = kcalloc(num_entries,
|
|
|
+ sizeof(struct cam_hw_fence_map_entry),
|
|
|
+ GFP_KERNEL);
|
|
|
+
|
|
|
+ if (!ctx->in_map_entries) {
|
|
|
+ CAM_ERR(CAM_CTXT, "%s[%d] no memory", ctx->dev_name, ctx->ctx_id);
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ num_entries = ctx->max_out_map_entries * CAM_ISP_CTX_REQ_MAX;
|
|
|
+ ctx->out_map_entries = kcalloc(num_entries,
|
|
|
+ sizeof(struct cam_hw_fence_map_entry),
|
|
|
+ GFP_KERNEL);
|
|
|
+
|
|
|
+ if (!ctx->out_map_entries) {
|
|
|
+ CAM_ERR(CAM_CTXT, "%s[%d] no memory", ctx->dev_name, ctx->ctx_id);
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ list_for_each_entry_safe(req, temp_req,
|
|
|
+ &ctx->free_req_list, list) {
|
|
|
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
|
|
|
+
|
|
|
+ req_isp->cfg =
|
|
|
+ &ctx->hw_update_entry[req->index * ctx->max_hw_update_entries];
|
|
|
+ req_isp->fence_map_in =
|
|
|
+ &ctx->in_map_entries[req->index * ctx->max_in_map_entries];
|
|
|
+ req_isp->fence_map_out =
|
|
|
+ &ctx->out_map_entries[req->index * ctx->max_out_map_entries];
|
|
|
+ }
|
|
|
+
|
|
|
+ return rc;
|
|
|
+
|
|
|
+end:
|
|
|
+ __cam_isp_ctx_free_mem_hw_entries(ctx);
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
|
|
|
struct cam_acquire_dev_cmd *cmd)
|
|
|
{
|
|
@@ -4671,6 +4743,13 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
|
|
|
param.num_acq = cmd->num_resources;
|
|
|
param.acquire_info = (uintptr_t) isp_res;
|
|
|
|
|
|
+ rc = __cam_isp_ctx_allocate_mem_hw_entries(ctx);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "Ctx[%d] allocate hw entry fail",
|
|
|
+ ctx->ctx_id);
|
|
|
+ goto free_res;
|
|
|
+ }
|
|
|
+
|
|
|
/* call HW manager to reserve the resource */
|
|
|
rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
|
|
|
¶m);
|
|
@@ -4833,6 +4912,13 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx,
|
|
|
param.acquire_info_size = cmd->data_size;
|
|
|
param.acquire_info = (uint64_t) acquire_hw_info;
|
|
|
|
|
|
+ rc = __cam_isp_ctx_allocate_mem_hw_entries(ctx);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "Ctx[%d] allocate hw entry fail",
|
|
|
+ ctx->ctx_id);
|
|
|
+ goto free_res;
|
|
|
+ }
|
|
|
+
|
|
|
/* call HW manager to reserve the resource */
|
|
|
rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
|
|
|
¶m);
|
|
@@ -4976,6 +5062,13 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
|
|
|
param.acquire_info_size = cmd->data_size;
|
|
|
param.acquire_info = (uint64_t) acquire_hw_info;
|
|
|
|
|
|
+ rc = __cam_isp_ctx_allocate_mem_hw_entries(ctx);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "Ctx[%d] allocate hw entry fail",
|
|
|
+ ctx->ctx_id);
|
|
|
+ goto free_res;
|
|
|
+ }
|
|
|
+
|
|
|
/* call HW manager to reserve the resource */
|
|
|
rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
|
|
|
¶m);
|
|
@@ -6014,6 +6107,10 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
|
|
|
ctx_base->state_machine = cam_isp_ctx_top_state_machine;
|
|
|
ctx_base->ctx_priv = ctx;
|
|
|
|
|
|
+ ctx_base->max_hw_update_entries = CAM_ISP_CTX_CFG_MAX;
|
|
|
+ ctx_base->max_in_map_entries = CAM_ISP_CTX_RES_MAX;
|
|
|
+ ctx_base->max_out_map_entries = CAM_ISP_CTX_RES_MAX;
|
|
|
+
|
|
|
/* initializing current state for error logging */
|
|
|
for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) {
|
|
|
ctx->cam_isp_ctx_state_monitor[i].curr_state =
|