mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
Merge "msm: camera: isp: Add support for offline IFE" into camera-kernel.lnx.4.0
This commit is contained in:
commit
6c7de8467b
15 changed files with 1215 additions and 583 deletions
|
|
@ -1028,6 +1028,96 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_isp_ctx_apply_req_offline(
|
||||
struct cam_context *ctx, uint32_t next_state,
|
||||
struct cam_isp_context *ctx_isp)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_ctx_request *req;
|
||||
struct cam_isp_ctx_req *req_isp;
|
||||
struct cam_hw_config_args cfg;
|
||||
|
||||
if (list_empty(&ctx->pending_req_list)) {
|
||||
CAM_DBG(CAM_ISP, "No pending requests to apply");
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ctx->state != CAM_CTX_ACTIVATED)
|
||||
goto end;
|
||||
|
||||
if (ctx_isp->active_req_cnt >= 2)
|
||||
goto end;
|
||||
|
||||
req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
|
||||
list);
|
||||
|
||||
CAM_DBG(CAM_REQ, "Apply request %lld in substate %d ctx %u",
|
||||
req->request_id, ctx_isp->substate_activated, ctx->ctx_id);
|
||||
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
|
||||
cfg.request_id = req->request_id;
|
||||
cfg.hw_update_entries = req_isp->cfg;
|
||||
cfg.num_hw_update_entries = req_isp->num_cfg;
|
||||
cfg.priv = &req_isp->hw_update_data;
|
||||
cfg.init_packet = 0;
|
||||
|
||||
rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
|
||||
if (rc) {
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
|
||||
} else {
|
||||
atomic_set(&ctx_isp->rxd_epoch, 0);
|
||||
ctx_isp->substate_activated = next_state;
|
||||
ctx_isp->last_applied_req_id = req->request_id;
|
||||
list_del_init(&req->list);
|
||||
list_add_tail(&req->list, &ctx->wait_req_list);
|
||||
CAM_DBG(CAM_ISP, "New substate state %d, applied req %lld",
|
||||
next_state, ctx_isp->last_applied_req_id);
|
||||
|
||||
__cam_isp_ctx_update_state_monitor_array(ctx_isp,
|
||||
CAM_ISP_STATE_CHANGE_TRIGGER_APPLIED,
|
||||
req->request_id);
|
||||
}
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_isp_ctx_offline_epoch_in_activated_state(
|
||||
struct cam_isp_context *ctx_isp, void *evt_data)
|
||||
{
|
||||
struct cam_context *ctx = ctx_isp->base;
|
||||
struct cam_ctx_request *req, *req_temp;
|
||||
uint64_t request_id = 0;
|
||||
|
||||
atomic_set(&ctx_isp->rxd_epoch, 1);
|
||||
|
||||
CAM_DBG(CAM_ISP, "SOF frame %lld ctx %u", ctx_isp->frame_id,
|
||||
ctx->ctx_id);
|
||||
|
||||
list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
|
||||
if (req->request_id > ctx_isp->reported_req_id) {
|
||||
request_id = req->request_id;
|
||||
ctx_isp->reported_req_id = request_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__cam_isp_ctx_apply_req_offline(ctx, CAM_ISP_CTX_ACTIVATED_APPLIED,
|
||||
ctx_isp);
|
||||
|
||||
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
|
||||
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
|
||||
|
||||
__cam_isp_ctx_update_state_monitor_array(ctx_isp,
|
||||
CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH,
|
||||
request_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cam_isp_ctx_reg_upd_in_epoch_bubble_state(
|
||||
struct cam_isp_context *ctx_isp, void *evt_data)
|
||||
{
|
||||
|
|
@ -1811,6 +1901,9 @@ end:
|
|||
|
||||
} while (req->request_id < ctx_isp->last_applied_req_id);
|
||||
|
||||
if (ctx_isp->offline_context)
|
||||
goto exit;
|
||||
|
||||
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) {
|
||||
notify.link_hdl = ctx->link_hdl;
|
||||
notify.dev_hdl = ctx->dev_hdl;
|
||||
|
|
@ -1861,6 +1954,7 @@ end:
|
|||
|
||||
CAM_DBG(CAM_ISP, "Exit");
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2244,6 +2338,63 @@ static struct cam_isp_ctx_irq_ops
|
|||
},
|
||||
};
|
||||
|
||||
static struct cam_isp_ctx_irq_ops
|
||||
cam_isp_ctx_offline_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = {
|
||||
/* SOF */
|
||||
{
|
||||
.irq_ops = {
|
||||
__cam_isp_ctx_handle_error,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
},
|
||||
/* APPLIED */
|
||||
{
|
||||
.irq_ops = {
|
||||
__cam_isp_ctx_handle_error,
|
||||
__cam_isp_ctx_sof_in_activated_state,
|
||||
__cam_isp_ctx_reg_upd_in_applied_state,
|
||||
NULL,
|
||||
NULL,
|
||||
__cam_isp_ctx_buf_done_in_applied,
|
||||
},
|
||||
},
|
||||
/* EPOCH */
|
||||
{
|
||||
.irq_ops = {
|
||||
__cam_isp_ctx_handle_error,
|
||||
NULL,
|
||||
NULL,
|
||||
__cam_isp_ctx_offline_epoch_in_activated_state,
|
||||
NULL,
|
||||
__cam_isp_ctx_buf_done_in_epoch,
|
||||
},
|
||||
},
|
||||
/* BUBBLE */
|
||||
{
|
||||
},
|
||||
/* Bubble Applied */
|
||||
{
|
||||
},
|
||||
/* HW ERROR */
|
||||
{
|
||||
.irq_ops = {
|
||||
NULL,
|
||||
__cam_isp_ctx_sof_in_activated_state,
|
||||
__cam_isp_ctx_reg_upd_in_hw_error,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
},
|
||||
/* HALT */
|
||||
{
|
||||
},
|
||||
};
|
||||
|
||||
static int __cam_isp_ctx_apply_req_in_activated_state(
|
||||
struct cam_context *ctx, struct cam_req_mgr_apply_request *apply,
|
||||
enum cam_isp_ctx_activated_substate next_state)
|
||||
|
|
@ -2796,6 +2947,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
|
|||
end:
|
||||
ctx_isp->bubble_frame_cnt = 0;
|
||||
atomic_set(&ctx_isp->process_bubble, 0);
|
||||
atomic_set(&ctx_isp->rxd_epoch, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -3685,8 +3837,11 @@ static int __cam_isp_ctx_config_dev_in_top_state(
|
|||
ctx->state);
|
||||
}
|
||||
} else {
|
||||
if (ctx->state != CAM_CTX_FLUSHED && ctx->state >= CAM_CTX_READY
|
||||
&& ctx->ctx_crm_intf->add_req) {
|
||||
if (ctx_isp->offline_context) {
|
||||
__cam_isp_ctx_enqueue_request_in_order(ctx, req);
|
||||
} else if ((ctx->state != CAM_CTX_FLUSHED) &&
|
||||
(ctx->state >= CAM_CTX_READY) &&
|
||||
ctx->ctx_crm_intf->add_req) {
|
||||
add_req.link_hdl = ctx->link_hdl;
|
||||
add_req.dev_hdl = ctx->dev_hdl;
|
||||
add_req.req_id = req->request_id;
|
||||
|
|
@ -3713,6 +3868,13 @@ static int __cam_isp_ctx_config_dev_in_top_state(
|
|||
"Preprocessing Config req_id %lld successful on ctx %u",
|
||||
req->request_id, ctx->ctx_id);
|
||||
|
||||
if (ctx_isp->offline_context && atomic_read(&ctx_isp->rxd_epoch)) {
|
||||
spin_lock_bh(&ctx->lock);
|
||||
__cam_isp_ctx_apply_req_offline(ctx,
|
||||
CAM_ISP_CTX_ACTIVATED_APPLIED, ctx_isp);
|
||||
spin_unlock_bh(&ctx->lock);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
put_ref:
|
||||
|
|
@ -3827,11 +3989,15 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
|
|||
cam_isp_ctx_rdi_only_activated_state_machine;
|
||||
ctx_isp->rdi_only_context = true;
|
||||
} else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) {
|
||||
CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI");
|
||||
CAM_DBG(CAM_ISP, "FS2 Session has PIX, RD and RDI");
|
||||
ctx_isp->substate_machine_irq =
|
||||
cam_isp_ctx_fs2_state_machine_irq;
|
||||
ctx_isp->substate_machine =
|
||||
cam_isp_ctx_fs2_state_machine;
|
||||
} else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_OFFLINE) {
|
||||
CAM_DBG(CAM_ISP, "offline Session has PIX and RD resources");
|
||||
ctx_isp->substate_machine_irq =
|
||||
cam_isp_ctx_offline_state_machine_irq;
|
||||
} else {
|
||||
CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
|
||||
ctx_isp->substate_machine_irq =
|
||||
|
|
@ -3985,11 +4151,16 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx,
|
|||
cam_isp_ctx_rdi_only_activated_state_machine;
|
||||
ctx_isp->rdi_only_context = true;
|
||||
} else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) {
|
||||
CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI");
|
||||
CAM_DBG(CAM_ISP, "FS2 Session has PIX, RD and RDI");
|
||||
ctx_isp->substate_machine_irq =
|
||||
cam_isp_ctx_fs2_state_machine_irq;
|
||||
ctx_isp->substate_machine =
|
||||
cam_isp_ctx_fs2_state_machine;
|
||||
} else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_OFFLINE) {
|
||||
CAM_DBG(CAM_ISP, "Offline session has PIX and RD resources");
|
||||
ctx_isp->substate_machine_irq =
|
||||
cam_isp_ctx_offline_state_machine_irq;
|
||||
ctx_isp->substate_machine = NULL;
|
||||
} else {
|
||||
CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
|
||||
ctx_isp->substate_machine_irq =
|
||||
|
|
@ -4136,11 +4307,17 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
|
|||
cam_isp_ctx_rdi_only_activated_state_machine;
|
||||
ctx_isp->rdi_only_context = true;
|
||||
} else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) {
|
||||
CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI");
|
||||
CAM_DBG(CAM_ISP, "FS2 Session has PIX, RD and RDI");
|
||||
ctx_isp->substate_machine_irq =
|
||||
cam_isp_ctx_fs2_state_machine_irq;
|
||||
ctx_isp->substate_machine =
|
||||
cam_isp_ctx_fs2_state_machine;
|
||||
} else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_OFFLINE) {
|
||||
CAM_DBG(CAM_ISP, "Offline Session has PIX and RD resources");
|
||||
ctx_isp->substate_machine_irq =
|
||||
cam_isp_ctx_offline_state_machine_irq;
|
||||
ctx_isp->substate_machine = NULL;
|
||||
ctx_isp->offline_context = true;
|
||||
} else {
|
||||
CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
|
||||
ctx_isp->substate_machine_irq =
|
||||
|
|
@ -4207,7 +4384,7 @@ static int __cam_isp_ctx_config_dev_in_acquired(struct cam_context *ctx,
|
|||
|
||||
rc = __cam_isp_ctx_config_dev_in_top_state(ctx, cmd);
|
||||
|
||||
if (!rc && (ctx->link_hdl >= 0)) {
|
||||
if (!rc && ((ctx->link_hdl >= 0) || ctx_isp->offline_context)) {
|
||||
ctx->state = CAM_CTX_READY;
|
||||
trace_cam_context_state("ISP", ctx);
|
||||
}
|
||||
|
|
@ -4368,6 +4545,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
|
|||
start_isp.start_only = false;
|
||||
|
||||
atomic_set(&ctx_isp->process_bubble, 0);
|
||||
atomic_set(&ctx_isp->rxd_epoch, 0);
|
||||
ctx_isp->frame_id = 0;
|
||||
ctx_isp->active_req_cnt = 0;
|
||||
ctx_isp->reported_req_id = 0;
|
||||
|
|
@ -4390,11 +4568,24 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
|
|||
*/
|
||||
list_del_init(&req->list);
|
||||
|
||||
if (ctx_isp->rdi_only_context || !req_isp->num_fence_map_out) {
|
||||
if (ctx_isp->offline_context && !req_isp->num_fence_map_out) {
|
||||
list_add_tail(&req->list, &ctx->free_req_list);
|
||||
atomic_set(&ctx_isp->rxd_epoch, 1);
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Move pending req: %lld to free list(cnt: %d) offline ctx %u",
|
||||
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
|
||||
} else if (ctx_isp->rdi_only_context || !req_isp->num_fence_map_out) {
|
||||
list_add_tail(&req->list, &ctx->wait_req_list);
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Move pending req: %lld to wait list(cnt: %d) ctx %u",
|
||||
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
|
||||
} else {
|
||||
list_add_tail(&req->list, &ctx->active_req_list);
|
||||
ctx_isp->active_req_cnt++;
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Move pending req: %lld to active list(cnt: %d) ctx %u offline %d",
|
||||
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id,
|
||||
ctx_isp->offline_context);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4539,6 +4730,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
|
|||
ctx_isp->last_applied_req_id = 0;
|
||||
ctx_isp->req_info.last_bufdone_req_id = 0;
|
||||
atomic_set(&ctx_isp->process_bubble, 0);
|
||||
atomic_set(&ctx_isp->rxd_epoch, 0);
|
||||
atomic64_set(&ctx_isp->state_monitor_head, -1);
|
||||
|
||||
for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++)
|
||||
|
|
|
|||
|
|
@ -247,13 +247,16 @@ struct cam_isp_context_event_record {
|
|||
* @event_record: Event record array
|
||||
* @rdi_only_context: Get context type information.
|
||||
* true, if context is rdi only context
|
||||
* @offline_context: Indicate whether context is for offline IFE
|
||||
* @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
|
||||
* @custom_enabled: Custom HW enabled for this ctx
|
||||
* @use_frame_header_ts: Use frame header for qtimer ts
|
||||
* @init_timestamp: Timestamp at which this context is initialized
|
||||
* @isp_device_type ISP device type
|
||||
* @isp_device_type: ISP device type
|
||||
* @rxd_epoch: Indicate whether epoch has been received. Used to
|
||||
* decide whether to apply request in offline ctx
|
||||
*
|
||||
*/
|
||||
struct cam_isp_context {
|
||||
|
|
@ -286,6 +289,7 @@ struct cam_isp_context {
|
|||
struct cam_isp_context_event_record event_record[
|
||||
CAM_ISP_CTX_EVENT_MAX][CAM_ISP_CTX_EVENT_RECORD_MAX_ENTRIES];
|
||||
bool rdi_only_context;
|
||||
bool offline_context;
|
||||
bool hw_acquired;
|
||||
bool init_received;
|
||||
bool split_acquire;
|
||||
|
|
@ -293,6 +297,7 @@ struct cam_isp_context {
|
|||
bool use_frame_header_ts;
|
||||
unsigned int init_timestamp;
|
||||
uint32_t isp_device_type;
|
||||
atomic_t rxd_epoch;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -979,90 +979,6 @@ static int cam_ife_mgr_process_base_info(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_acquire_res_bus_rd(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_in_port_generic_info *in_port)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
struct cam_vfe_acquire_args vfe_acquire;
|
||||
struct cam_isp_hw_mgr_res *ife_in_rd_res;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_isp_hw_mgr_res *ife_src_res;
|
||||
int i;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Enter");
|
||||
|
||||
list_for_each_entry(ife_src_res, &ife_ctx->res_list_ife_src, list) {
|
||||
if (ife_src_res->res_id != CAM_ISP_HW_VFE_IN_RD)
|
||||
continue;
|
||||
|
||||
rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
|
||||
&ife_in_rd_res);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "No more free hw mgr resource");
|
||||
goto err;
|
||||
}
|
||||
cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_in_rd,
|
||||
&ife_in_rd_res);
|
||||
|
||||
vfe_acquire.rsrc_type = CAM_ISP_RESOURCE_VFE_BUS_RD;
|
||||
vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
|
||||
vfe_acquire.vfe_out.cdm_ops = ife_ctx->cdm_ops;
|
||||
vfe_acquire.priv = ife_ctx;
|
||||
vfe_acquire.vfe_out.unique_id = ife_ctx->ctx_index;
|
||||
vfe_acquire.vfe_out.is_dual = ife_src_res->is_dual_isp;
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (!ife_src_res->hw_res[i])
|
||||
continue;
|
||||
|
||||
hw_intf = ife_src_res->hw_res[i]->hw_intf;
|
||||
if (i == CAM_ISP_HW_SPLIT_LEFT) {
|
||||
vfe_acquire.vfe_out.split_id =
|
||||
CAM_ISP_HW_SPLIT_LEFT;
|
||||
if (ife_src_res->is_dual_isp) {
|
||||
/*TBD */
|
||||
vfe_acquire.vfe_out.is_master = 1;
|
||||
vfe_acquire.vfe_out.dual_slave_core =
|
||||
ife_ctx->slave_hw_idx;
|
||||
} else {
|
||||
vfe_acquire.vfe_out.is_master = 0;
|
||||
vfe_acquire.vfe_out.dual_slave_core =
|
||||
0;
|
||||
}
|
||||
} else {
|
||||
vfe_acquire.vfe_out.split_id =
|
||||
CAM_ISP_HW_SPLIT_RIGHT;
|
||||
vfe_acquire.vfe_out.is_master = 0;
|
||||
vfe_acquire.vfe_out.dual_slave_core =
|
||||
ife_ctx->master_hw_idx;
|
||||
}
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
||||
&vfe_acquire,
|
||||
sizeof(struct cam_vfe_acquire_args));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Can not acquire out resource 0x%x",
|
||||
vfe_acquire.rsrc_type);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ife_in_rd_res->hw_res[i] =
|
||||
vfe_acquire.vfe_out.rsrc_node;
|
||||
CAM_DBG(CAM_ISP, "resource type :0x%x res id:0x%x",
|
||||
ife_in_rd_res->hw_res[i]->res_type,
|
||||
ife_in_rd_res->hw_res[i]->res_id);
|
||||
|
||||
}
|
||||
ife_in_rd_res->is_dual_isp = in_port->usage_type;
|
||||
ife_in_rd_res->res_type = CAM_ISP_RESOURCE_VFE_BUS_RD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
CAM_DBG(CAM_ISP, "Exit rc(0x%x)", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_acquire_res_ife_out_rdi(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_hw_mgr_res *ife_src_res,
|
||||
|
|
@ -1297,125 +1213,6 @@ err:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_acquire_res_ife_rd_src(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_in_port_generic_info *in_port)
|
||||
{
|
||||
int rc = -1;
|
||||
struct cam_isp_hw_mgr_res *csid_res;
|
||||
struct cam_isp_hw_mgr_res *ife_src_res;
|
||||
struct cam_vfe_acquire_args vfe_acquire;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_ife_hw_mgr *ife_hw_mgr;
|
||||
int vfe_idx = -1, i = 0;
|
||||
|
||||
ife_hw_mgr = ife_ctx->hw_mgr;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Enter");
|
||||
list_for_each_entry(csid_res, &ife_ctx->res_list_ife_csid, list) {
|
||||
if (csid_res->res_id != CAM_IFE_PIX_PATH_RES_RDI_0) {
|
||||
CAM_DBG(CAM_ISP, "not RDI0: %d", csid_res->res_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
|
||||
&ife_src_res);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "No more free hw mgr resource");
|
||||
goto err;
|
||||
}
|
||||
cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_src,
|
||||
&ife_src_res);
|
||||
|
||||
CAM_DBG(CAM_ISP, "csid_res_id %d", csid_res->res_id);
|
||||
vfe_acquire.rsrc_type = CAM_ISP_RESOURCE_VFE_IN;
|
||||
vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
|
||||
vfe_acquire.vfe_in.cdm_ops = ife_ctx->cdm_ops;
|
||||
vfe_acquire.vfe_in.in_port = in_port;
|
||||
vfe_acquire.vfe_in.res_id = CAM_ISP_HW_VFE_IN_RD;
|
||||
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE;
|
||||
|
||||
ife_src_res->res_type = vfe_acquire.rsrc_type;
|
||||
ife_src_res->res_id = vfe_acquire.vfe_in.res_id;
|
||||
ife_src_res->is_dual_isp = csid_res->is_dual_isp;
|
||||
|
||||
hw_intf =
|
||||
ife_hw_mgr->ife_devices[csid_res->hw_res[
|
||||
CAM_ISP_HW_SPLIT_LEFT]->hw_intf->hw_idx];
|
||||
|
||||
vfe_idx = csid_res->hw_res[
|
||||
CAM_ISP_HW_SPLIT_LEFT]->hw_intf->hw_idx;
|
||||
|
||||
/*
|
||||
* fill in more acquire information as needed
|
||||
*/
|
||||
if (ife_src_res->is_dual_isp)
|
||||
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_MASTER;
|
||||
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
||||
&vfe_acquire,
|
||||
sizeof(struct cam_vfe_acquire_args));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Can not acquire IFE HW res %d",
|
||||
csid_res->res_id);
|
||||
goto err;
|
||||
}
|
||||
ife_src_res->hw_res[CAM_ISP_HW_SPLIT_LEFT] =
|
||||
vfe_acquire.vfe_in.rsrc_node;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"acquire success IFE:%d res type :0x%x res id:0x%x",
|
||||
hw_intf->hw_idx,
|
||||
ife_src_res->hw_res[CAM_ISP_HW_SPLIT_LEFT]->res_type,
|
||||
ife_src_res->hw_res[CAM_ISP_HW_SPLIT_LEFT]->res_id);
|
||||
|
||||
if (!ife_src_res->is_dual_isp)
|
||||
goto acq;
|
||||
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (i == CAM_ISP_HW_SPLIT_LEFT) {
|
||||
CAM_DBG(CAM_ISP, "vfe_idx %d is acquired",
|
||||
vfe_idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
hw_intf = ife_hw_mgr->ife_devices[i];
|
||||
|
||||
/* fill in more acquire information as needed */
|
||||
if (i == CAM_ISP_HW_SPLIT_RIGHT)
|
||||
vfe_acquire.vfe_in.sync_mode =
|
||||
CAM_ISP_HW_SYNC_SLAVE;
|
||||
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
||||
&vfe_acquire,
|
||||
sizeof(struct cam_vfe_acquire_args));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Can not acquire IFE HW res %d",
|
||||
csid_res->res_id);
|
||||
goto err;
|
||||
}
|
||||
ife_src_res->hw_res[i] = vfe_acquire.vfe_in.rsrc_node;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"acquire success IFE:%d res type :0x%x res id:0x%x",
|
||||
hw_intf->hw_idx,
|
||||
ife_src_res->hw_res[i]->res_type,
|
||||
ife_src_res->hw_res[i]->res_id);
|
||||
}
|
||||
acq:
|
||||
/*
|
||||
* It should be one to one mapping between
|
||||
* csid resource and ife source resource
|
||||
*/
|
||||
csid_res->num_children++;
|
||||
}
|
||||
|
||||
err:
|
||||
/* release resource at the entry function */
|
||||
CAM_DBG(CAM_ISP, "Exit rc %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_convert_hw_idx_to_ife_hw_num(int hw_idx)
|
||||
{
|
||||
uint32_t hw_version, rc = 0;
|
||||
|
|
@ -1547,6 +1344,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_src(
|
|||
vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
|
||||
vfe_acquire.vfe_in.cdm_ops = ife_ctx->cdm_ops;
|
||||
vfe_acquire.vfe_in.in_port = in_port;
|
||||
vfe_acquire.vfe_in.is_fe_enabled = ife_ctx->is_fe_enabled;
|
||||
vfe_acquire.vfe_in.is_offline = ife_ctx->is_offline;
|
||||
vfe_acquire.priv = ife_ctx;
|
||||
vfe_acquire.event_cb = cam_ife_hw_mgr_event_handler;
|
||||
|
||||
|
|
@ -1800,7 +1599,7 @@ static int cam_ife_mgr_acquire_cid_res(
|
|||
|
||||
/* Acquire Left if not already acquired */
|
||||
/* For dual IFE cases, start acquiring the lower idx first */
|
||||
if (ife_ctx->is_fe_enable || in_port->usage_type)
|
||||
if (ife_ctx->is_fe_enabled || in_port->usage_type)
|
||||
rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr,
|
||||
&csid_acquire, true);
|
||||
else
|
||||
|
|
@ -2166,7 +1965,7 @@ static int cam_ife_hw_mgr_acquire_res_root(
|
|||
ife_ctx->res_list_ife_in.res_id = in_port->res_type;
|
||||
ife_ctx->res_list_ife_in.is_dual_isp = in_port->usage_type;
|
||||
} else if ((ife_ctx->res_list_ife_in.res_id !=
|
||||
in_port->res_type) && (!ife_ctx->is_fe_enable)) {
|
||||
in_port->res_type) && (!ife_ctx->is_fe_enabled)) {
|
||||
CAM_ERR(CAM_ISP, "No Free resource for this context");
|
||||
goto err;
|
||||
} else {
|
||||
|
|
@ -2211,14 +2010,14 @@ static int cam_ife_mgr_check_and_update_fe_v0(
|
|||
CAM_DBG(CAM_ISP, "in_port%d res_type %d", i,
|
||||
in_port->res_type);
|
||||
if (in_port->res_type == CAM_ISP_IFE_IN_RES_RD) {
|
||||
ife_ctx->is_fe_enable = true;
|
||||
ife_ctx->is_fe_enabled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
in_port = (struct cam_isp_in_port_info *)((uint8_t *)in_port +
|
||||
in_port_length);
|
||||
}
|
||||
CAM_DBG(CAM_ISP, "is_fe_enable %d", ife_ctx->is_fe_enable);
|
||||
CAM_DBG(CAM_ISP, "is_fe_enabled %d", ife_ctx->is_fe_enabled);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2256,14 +2055,17 @@ static int cam_ife_mgr_check_and_update_fe_v2(
|
|||
CAM_DBG(CAM_ISP, "in_port%d res_type %d", i,
|
||||
in_port->res_type);
|
||||
if (in_port->res_type == CAM_ISP_IFE_IN_RES_RD) {
|
||||
ife_ctx->is_fe_enable = true;
|
||||
ife_ctx->is_fe_enabled = true;
|
||||
if (in_port->offline_mode)
|
||||
ife_ctx->is_offline = true;
|
||||
break;
|
||||
}
|
||||
|
||||
in_port = (struct cam_isp_in_port_info_v2 *)
|
||||
((uint8_t *)in_port + in_port_length);
|
||||
}
|
||||
CAM_DBG(CAM_ISP, "is_fe_enable %d", ife_ctx->is_fe_enable);
|
||||
CAM_DBG(CAM_ISP, "is_fe_enabled %d is_offline %d",
|
||||
ife_ctx->is_fe_enabled, ife_ctx->is_offline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2316,22 +2118,21 @@ static int cam_ife_hw_mgr_preprocess_port(
|
|||
|
||||
ife_hw_mgr = ife_ctx->hw_mgr;
|
||||
|
||||
if (in_port->res_type == CAM_ISP_IFE_IN_RES_RD) {
|
||||
if (in_port->res_type == CAM_ISP_IFE_IN_RES_RD)
|
||||
ife_rd_num++;
|
||||
} else {
|
||||
for (i = 0; i < in_port->num_out_res; i++) {
|
||||
out_port = &in_port->data[i];
|
||||
if (cam_ife_hw_mgr_is_rdi_res(out_port->res_type))
|
||||
rdi_num++;
|
||||
else if (out_port->res_type == CAM_ISP_IFE_OUT_RES_2PD)
|
||||
ppp_num++;
|
||||
else if (out_port->res_type == CAM_ISP_IFE_OUT_RES_LCR)
|
||||
lcr_num++;
|
||||
else {
|
||||
CAM_DBG(CAM_ISP, "out_res_type %d",
|
||||
out_port->res_type);
|
||||
ipp_num++;
|
||||
}
|
||||
|
||||
for (i = 0; i < in_port->num_out_res; i++) {
|
||||
out_port = &in_port->data[i];
|
||||
if (cam_ife_hw_mgr_is_rdi_res(out_port->res_type))
|
||||
rdi_num++;
|
||||
else if (out_port->res_type == CAM_ISP_IFE_OUT_RES_2PD)
|
||||
ppp_num++;
|
||||
else if (out_port->res_type == CAM_ISP_IFE_OUT_RES_LCR)
|
||||
lcr_num++;
|
||||
else {
|
||||
CAM_DBG(CAM_ISP, "out_res_type %d",
|
||||
out_port->res_type);
|
||||
ipp_num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2347,6 +2148,290 @@ static int cam_ife_hw_mgr_preprocess_port(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_acquire_offline_res_ife_bus_rd(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_in_port_generic_info *in_port)
|
||||
{
|
||||
int rc = -EINVAL, j;
|
||||
int i = CAM_ISP_HW_SPLIT_LEFT;
|
||||
struct cam_vfe_acquire_args vfe_acquire;
|
||||
struct cam_isp_hw_mgr_res *ife_bus_rd_res;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_ife_hw_mgr *ife_hw_mgr;
|
||||
|
||||
ife_hw_mgr = ife_ctx->hw_mgr;
|
||||
|
||||
rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &ife_bus_rd_res);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "No more free hw mgr resource");
|
||||
goto end;
|
||||
}
|
||||
|
||||
vfe_acquire.rsrc_type = CAM_ISP_RESOURCE_VFE_BUS_RD;
|
||||
vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
|
||||
vfe_acquire.priv = ife_ctx;
|
||||
vfe_acquire.event_cb = cam_ife_hw_mgr_event_handler;
|
||||
|
||||
vfe_acquire.vfe_bus_rd.cdm_ops = ife_ctx->cdm_ops;
|
||||
vfe_acquire.vfe_bus_rd.is_dual = (uint32_t)ife_ctx->is_dual;
|
||||
vfe_acquire.vfe_bus_rd.is_offline = ife_ctx->is_offline;
|
||||
vfe_acquire.vfe_bus_rd.res_id = CAM_ISP_HW_VFE_IN_RD;
|
||||
vfe_acquire.vfe_bus_rd.unpacker_fmt = in_port->fe_unpacker_fmt;
|
||||
|
||||
for (j = 0; j < CAM_IFE_HW_NUM_MAX; j++) {
|
||||
if (!ife_hw_mgr->ife_devices[j])
|
||||
continue;
|
||||
|
||||
hw_intf = ife_hw_mgr->ife_devices[j];
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
||||
&vfe_acquire, sizeof(struct cam_vfe_acquire_args));
|
||||
|
||||
if (!rc) {
|
||||
ife_bus_rd_res->hw_res[i] =
|
||||
vfe_acquire.vfe_bus_rd.rsrc_node;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Acquired VFE:%d BUS RD for LEFT", j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == CAM_IFE_HW_NUM_MAX || !vfe_acquire.vfe_bus_rd.rsrc_node) {
|
||||
CAM_ERR(CAM_ISP, "Failed to acquire BUS RD for LEFT", i);
|
||||
goto put_res;
|
||||
}
|
||||
|
||||
ife_bus_rd_res->res_type = vfe_acquire.rsrc_type;
|
||||
ife_bus_rd_res->res_id = vfe_acquire.vfe_in.res_id;
|
||||
ife_bus_rd_res->is_dual_isp = (uint32_t)ife_ctx->is_dual;
|
||||
cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_in_rd, &ife_bus_rd_res);
|
||||
|
||||
if (ife_ctx->is_dual) {
|
||||
for (j = 0; j < CAM_IFE_HW_NUM_MAX; j++) {
|
||||
if (!ife_hw_mgr->ife_devices[j])
|
||||
continue;
|
||||
|
||||
if (j == ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx)
|
||||
continue;
|
||||
|
||||
hw_intf = ife_hw_mgr->ife_devices[j];
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
||||
&vfe_acquire,
|
||||
sizeof(struct cam_vfe_acquire_args));
|
||||
|
||||
if (!rc) {
|
||||
ife_bus_rd_res->hw_res[++i] =
|
||||
vfe_acquire.vfe_bus_rd.rsrc_node;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Acquired VFE:%d BUS RD for RIGHT", j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == CAM_IFE_HW_NUM_MAX ||
|
||||
!vfe_acquire.vfe_bus_rd.rsrc_node) {
|
||||
CAM_ERR(CAM_ISP, "Failed to acquire BUS RD for RIGHT");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
put_res:
|
||||
cam_ife_hw_mgr_put_res(&ife_ctx->free_res_list, &ife_bus_rd_res);
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_acquire_offline_res_ife_camif(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_in_port_generic_info *in_port,
|
||||
bool acquire_lcr,
|
||||
uint32_t *acquired_hw_id,
|
||||
uint32_t *acquired_hw_path)
|
||||
{
|
||||
int rc = -1;
|
||||
int i = CAM_ISP_HW_SPLIT_LEFT;
|
||||
struct cam_isp_hw_mgr_res *ife_src_res;
|
||||
struct cam_isp_hw_mgr_res *ife_bus_rd_res;
|
||||
struct cam_vfe_acquire_args vfe_acquire;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_ife_hw_mgr *ife_hw_mgr;
|
||||
|
||||
ife_hw_mgr = ife_ctx->hw_mgr;
|
||||
|
||||
ife_bus_rd_res = list_first_entry(&ife_ctx->res_list_ife_in_rd,
|
||||
struct cam_isp_hw_mgr_res, list);
|
||||
|
||||
if (!ife_bus_rd_res) {
|
||||
CAM_ERR(CAM_ISP, "BUS RD resource has not been acquired");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &ife_src_res);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "No free resource");
|
||||
goto end;
|
||||
}
|
||||
|
||||
vfe_acquire.rsrc_type = CAM_ISP_RESOURCE_VFE_IN;
|
||||
vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
|
||||
vfe_acquire.priv = ife_ctx;
|
||||
vfe_acquire.event_cb = cam_ife_hw_mgr_event_handler;
|
||||
|
||||
vfe_acquire.vfe_in.cdm_ops = ife_ctx->cdm_ops;
|
||||
vfe_acquire.vfe_in.in_port = in_port;
|
||||
vfe_acquire.vfe_in.is_fe_enabled = ife_ctx->is_fe_enabled;
|
||||
vfe_acquire.vfe_in.is_offline = ife_ctx->is_offline;
|
||||
|
||||
if (!acquire_lcr)
|
||||
vfe_acquire.vfe_in.res_id = CAM_ISP_HW_VFE_IN_CAMIF;
|
||||
else
|
||||
vfe_acquire.vfe_in.res_id = CAM_ISP_HW_VFE_IN_LCR;
|
||||
|
||||
if (ife_ctx->is_dual)
|
||||
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_MASTER;
|
||||
else
|
||||
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE;
|
||||
|
||||
hw_intf = ife_hw_mgr->ife_devices[
|
||||
ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx];
|
||||
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire,
|
||||
sizeof(struct cam_vfe_acquire_args));
|
||||
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Failed to acquire CAMIF for LEFT");
|
||||
goto put_res;
|
||||
}
|
||||
|
||||
ife_src_res->hw_res[i] = vfe_acquire.vfe_in.rsrc_node;
|
||||
|
||||
*acquired_hw_id |= cam_convert_hw_idx_to_ife_hw_num(
|
||||
hw_intf->hw_idx);
|
||||
|
||||
acquired_hw_path[i] |= cam_convert_res_id_to_hw_path(
|
||||
ife_src_res->hw_res[i]->res_id);
|
||||
|
||||
CAM_DBG(CAM_ISP, "Acquired VFE:%d CAMIF for LEFT",
|
||||
ife_src_res->hw_res[i]->hw_intf->hw_idx);
|
||||
|
||||
ife_src_res->res_type = vfe_acquire.rsrc_type;
|
||||
ife_src_res->res_id = vfe_acquire.vfe_in.res_id;
|
||||
ife_src_res->is_dual_isp = (uint32_t)ife_ctx->is_dual;
|
||||
cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_src, &ife_src_res);
|
||||
|
||||
if (ife_ctx->is_dual) {
|
||||
vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_SLAVE;
|
||||
|
||||
hw_intf = ife_hw_mgr->ife_devices[
|
||||
ife_bus_rd_res->hw_res[++i]->hw_intf->hw_idx];
|
||||
|
||||
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire,
|
||||
sizeof(struct cam_vfe_acquire_args));
|
||||
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Failed to acquire CAMIF for RIGHT");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ife_src_res->hw_res[i] = vfe_acquire.vfe_in.rsrc_node;
|
||||
|
||||
*acquired_hw_id |= cam_convert_hw_idx_to_ife_hw_num(
|
||||
hw_intf->hw_idx);
|
||||
|
||||
acquired_hw_path[i] |= cam_convert_res_id_to_hw_path(
|
||||
ife_src_res->hw_res[i]->res_id);
|
||||
|
||||
CAM_DBG(CAM_ISP, "Acquired VFE:%d CAMIF for RIGHT",
|
||||
ife_src_res->hw_res[i]->hw_intf->hw_idx);
|
||||
}
|
||||
|
||||
ife_bus_rd_res->num_children++;
|
||||
|
||||
return rc;
|
||||
|
||||
put_res:
|
||||
cam_ife_hw_mgr_put_res(&ife_ctx->free_res_list, &ife_src_res);
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_acquire_hw_for_fe_ctx(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_in_port_generic_info *in_port,
|
||||
uint32_t *num_pix_port,
|
||||
uint32_t *acquired_hw_id,
|
||||
uint32_t *acquired_hw_path)
|
||||
{
|
||||
int rc = -1;
|
||||
int ipp_count = 0;
|
||||
int rdi_count = 0;
|
||||
int ppp_count = 0;
|
||||
int ife_rd_count = 0;
|
||||
int lcr_count = 0;
|
||||
|
||||
ife_ctx->is_dual = (bool)in_port->usage_type;
|
||||
|
||||
cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port, &ipp_count,
|
||||
&rdi_count, &ppp_count, &ife_rd_count, &lcr_count);
|
||||
|
||||
if ((!ipp_count && !lcr_count) || !ife_rd_count) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid %d BUS RD %d PIX %d LCR ports for FE ctx");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rdi_count || ppp_count) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"%d RDI %d PPP ports invalid for FE ctx",
|
||||
rdi_count, ppp_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cam_ife_hw_mgr_acquire_offline_res_ife_bus_rd(ife_ctx, in_port);
|
||||
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Acquire IFE BUS RD resource Failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ipp_count)
|
||||
rc = cam_ife_hw_mgr_acquire_offline_res_ife_camif(ife_ctx,
|
||||
in_port, false, acquired_hw_id, acquired_hw_path);
|
||||
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Acquire IFE IPP SRC resource Failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (lcr_count)
|
||||
rc = cam_ife_hw_mgr_acquire_offline_res_ife_camif(ife_ctx,
|
||||
in_port, true, acquired_hw_id, acquired_hw_path);
|
||||
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Acquire IFE LCR SRC resource Failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = cam_ife_hw_mgr_acquire_res_ife_out(ife_ctx, in_port);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Acquire IFE OUT resource Failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
*num_pix_port += ipp_count + lcr_count;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int cam_ife_mgr_acquire_hw_for_ctx(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
struct cam_isp_in_port_generic_info *in_port,
|
||||
|
|
@ -2373,10 +2458,14 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
|
|||
cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port, &ipp_count,
|
||||
&rdi_count, &ppp_count, &ife_rd_count, &lcr_count);
|
||||
|
||||
if (!ipp_count && !rdi_count && !ppp_count && !ife_rd_count
|
||||
&& !lcr_count) {
|
||||
if (ife_rd_count) {
|
||||
CAM_ERR(CAM_ISP, "Invalid BUS RD port for non-FE ctx");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ipp_count && !rdi_count && !ppp_count && !lcr_count) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"No PIX or RDI or PPP or IFE RD or LCR resource");
|
||||
"No PIX or RDI or PPP or LCR resource");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -2421,15 +2510,7 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
|
|||
}
|
||||
|
||||
/* get ife src resource */
|
||||
if (ife_rd_count) {
|
||||
rc = cam_ife_hw_mgr_acquire_res_ife_rd_src(ife_ctx, in_port);
|
||||
rc = cam_ife_hw_mgr_acquire_res_bus_rd(ife_ctx, in_port);
|
||||
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Acquire IFE RD SRC resource Failed");
|
||||
goto err;
|
||||
}
|
||||
} else if (ipp_count || ppp_count || rdi_count) {
|
||||
if (ipp_count || ppp_count || rdi_count) {
|
||||
rc = cam_ife_hw_mgr_acquire_res_ife_src(ife_ctx,
|
||||
in_port, false,
|
||||
acquired_hw_id, acquired_hw_path);
|
||||
|
|
@ -2633,10 +2714,12 @@ static int cam_ife_mgr_acquire_get_unified_structure_v2(
|
|||
|
||||
if (port_info->num_valid_vc_dt == 0 ||
|
||||
port_info->num_valid_vc_dt >= CAM_ISP_VC_DT_CFG) {
|
||||
CAM_ERR(CAM_ISP, "Invalid i/p arg invalid vc-dt: %d",
|
||||
in->num_valid_vc_dt);
|
||||
rc = -EINVAL;
|
||||
goto release_mem;
|
||||
if (in->res_type != CAM_ISP_IFE_IN_RES_RD) {
|
||||
CAM_ERR(CAM_ISP, "Invalid i/p arg invalid vc-dt: %d",
|
||||
in->num_valid_vc_dt);
|
||||
rc = -EINVAL;
|
||||
goto release_mem;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < port_info->num_valid_vc_dt; i++) {
|
||||
|
|
@ -2644,26 +2727,27 @@ static int cam_ife_mgr_acquire_get_unified_structure_v2(
|
|||
port_info->dt[i] = in->dt[i];
|
||||
}
|
||||
|
||||
port_info->format = in->format;
|
||||
port_info->test_pattern = in->test_pattern;
|
||||
port_info->usage_type = in->usage_type;
|
||||
port_info->left_start = in->left_start;
|
||||
port_info->left_stop = in->left_stop;
|
||||
port_info->left_width = in->left_width;
|
||||
port_info->right_start = in->right_start;
|
||||
port_info->right_stop = in->right_stop;
|
||||
port_info->right_width = in->right_width;
|
||||
port_info->line_start = in->line_start;
|
||||
port_info->line_stop = in->line_stop;
|
||||
port_info->height = in->height;
|
||||
port_info->pixel_clk = in->pixel_clk;
|
||||
port_info->batch_size = in->batch_size;
|
||||
port_info->dsp_mode = in->dsp_mode;
|
||||
port_info->hbi_cnt = in->hbi_cnt;
|
||||
port_info->cust_node = in->cust_node;
|
||||
port_info->horizontal_bin = in->horizontal_bin;
|
||||
port_info->qcfa_bin = in->qcfa_bin;
|
||||
port_info->num_out_res = in->num_out_res;
|
||||
port_info->format = in->format;
|
||||
port_info->test_pattern = in->test_pattern;
|
||||
port_info->usage_type = in->usage_type;
|
||||
port_info->left_start = in->left_start;
|
||||
port_info->left_stop = in->left_stop;
|
||||
port_info->left_width = in->left_width;
|
||||
port_info->right_start = in->right_start;
|
||||
port_info->right_stop = in->right_stop;
|
||||
port_info->right_width = in->right_width;
|
||||
port_info->line_start = in->line_start;
|
||||
port_info->line_stop = in->line_stop;
|
||||
port_info->height = in->height;
|
||||
port_info->pixel_clk = in->pixel_clk;
|
||||
port_info->batch_size = in->batch_size;
|
||||
port_info->dsp_mode = in->dsp_mode;
|
||||
port_info->fe_unpacker_fmt = in->format;
|
||||
port_info->hbi_cnt = in->hbi_cnt;
|
||||
port_info->cust_node = in->cust_node;
|
||||
port_info->horizontal_bin = in->horizontal_bin;
|
||||
port_info->qcfa_bin = in->qcfa_bin;
|
||||
port_info->num_out_res = in->num_out_res;
|
||||
|
||||
port_info->data = kcalloc(in->num_out_res,
|
||||
sizeof(struct cam_isp_out_port_generic_info),
|
||||
|
|
@ -2822,10 +2906,17 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
|||
goto free_mem;
|
||||
}
|
||||
|
||||
rc = cam_ife_mgr_acquire_hw_for_ctx(ife_ctx, in_port,
|
||||
&num_pix_port_per_in, &num_rdi_port_per_in,
|
||||
&acquire_args->acquired_hw_id[i],
|
||||
acquire_args->acquired_hw_path[i]);
|
||||
if (ife_ctx->is_fe_enabled)
|
||||
rc = cam_ife_mgr_acquire_hw_for_fe_ctx(
|
||||
ife_ctx, in_port,
|
||||
&num_pix_port_per_in,
|
||||
&acquire_args->acquired_hw_id[i],
|
||||
acquire_args->acquired_hw_path[i]);
|
||||
else
|
||||
rc = cam_ife_mgr_acquire_hw_for_ctx(ife_ctx, in_port,
|
||||
&num_pix_port_per_in, &num_rdi_port_per_in,
|
||||
&acquire_args->acquired_hw_id[i],
|
||||
acquire_args->acquired_hw_path[i]);
|
||||
|
||||
total_pix_port += num_pix_port_per_in;
|
||||
total_rdi_port += num_rdi_port_per_in;
|
||||
|
|
@ -2915,6 +3006,7 @@ void cam_ife_mgr_acquire_get_unified_dev_str(struct cam_isp_in_port_info *in,
|
|||
gen_port_info->batch_size = in->batch_size;
|
||||
gen_port_info->dsp_mode = in->dsp_mode;
|
||||
gen_port_info->hbi_cnt = in->hbi_cnt;
|
||||
gen_port_info->fe_unpacker_fmt = in->format;
|
||||
gen_port_info->cust_node = 0;
|
||||
gen_port_info->num_out_res = in->num_out_res;
|
||||
|
||||
|
|
@ -3788,11 +3880,6 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|||
for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++)
|
||||
cam_ife_hw_mgr_stop_hw_res(&ctx->res_list_ife_out[i]);
|
||||
|
||||
/* IFE bus rd resources */
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_in_rd, list) {
|
||||
cam_ife_hw_mgr_stop_hw_res(hw_mgr_res);
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "Going to stop IFE Mux");
|
||||
|
||||
/* IFE mux in resources */
|
||||
|
|
@ -3800,6 +3887,11 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|||
cam_ife_hw_mgr_stop_hw_res(hw_mgr_res);
|
||||
}
|
||||
|
||||
/* IFE bus rd resources */
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_in_rd, list) {
|
||||
cam_ife_hw_mgr_stop_hw_res(hw_mgr_res);
|
||||
}
|
||||
|
||||
cam_tasklet_stop(ctx->common.tasklet_info);
|
||||
|
||||
cam_ife_mgr_pause_hw(ctx);
|
||||
|
|
@ -4090,18 +4182,6 @@ start_only:
|
|||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "START IFE BUS RD ... in ctx id:%d",
|
||||
ctx->ctx_index);
|
||||
/* Start the IFE mux in devices */
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_in_rd, list) {
|
||||
rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Can not start IFE BUS RD (%d)",
|
||||
hw_mgr_res->res_id);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (primary_rdi_out_res < CAM_ISP_IFE_OUT_RES_MAX)
|
||||
primary_rdi_src_res =
|
||||
cam_convert_rdi_out_res_id_to_src(primary_rdi_out_res);
|
||||
|
|
@ -4114,15 +4194,25 @@ start_only:
|
|||
hw_mgr_res->hw_res[0]->rdi_only_ctx =
|
||||
ctx->is_rdi_only_context;
|
||||
}
|
||||
|
||||
rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)",
|
||||
CAM_ERR(CAM_ISP, "Can not start IFE Mux (%d)",
|
||||
hw_mgr_res->res_id);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "START IFE BUS RD ... in ctx id:%d", ctx->ctx_index);
|
||||
/* Start IFE Bus RD devices */
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_in_rd, list) {
|
||||
rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Can not start IFE BUS RD (%d)",
|
||||
hw_mgr_res->res_id);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d",
|
||||
ctx->ctx_index);
|
||||
/* Start the IFE CSID HW devices */
|
||||
|
|
@ -5838,6 +5928,18 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* add go_cmd for offline context */
|
||||
if (prepare->num_out_map_entries && prepare->num_in_map_entries &&
|
||||
ctx->is_offline) {
|
||||
rc = cam_isp_add_go_cmd(prepare, &ctx->res_list_ife_in_rd,
|
||||
ctx->base[i].idx, &kmd_buf);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Add GO_CMD faled i: %d, idx: %d, rc: %d",
|
||||
i, ctx->base[i].idx, rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* reg update will be done later for the initial configure.
|
||||
* need to plus one to the op_code and only take the lower
|
||||
|
|
@ -6075,7 +6177,10 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
|||
isp_hw_cmd_args->u.sof_irq_enable);
|
||||
break;
|
||||
case CAM_ISP_HW_MGR_CMD_CTX_TYPE:
|
||||
if (ctx->is_fe_enable)
|
||||
if (ctx->is_fe_enabled && ctx->is_offline)
|
||||
isp_hw_cmd_args->u.ctx_type =
|
||||
CAM_ISP_CTX_OFFLINE;
|
||||
else if (ctx->is_fe_enabled && !ctx->is_offline)
|
||||
isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_FS2;
|
||||
else if (ctx->is_rdi_only_context)
|
||||
isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_RDI;
|
||||
|
|
@ -6309,6 +6414,17 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static inline void cam_ife_hw_mgr_get_offline_sof_timestamp(
|
||||
uint64_t *timestamp,
|
||||
uint64_t *boot_time)
|
||||
{
|
||||
struct timespec64 ts;
|
||||
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
*timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec);
|
||||
*boot_time = *timestamp;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_cmd_get_sof_timestamp(
|
||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||
uint64_t *time_stamp,
|
||||
|
|
@ -6681,6 +6797,7 @@ static int cam_ife_hw_mgr_handle_hw_rup(
|
|||
|
||||
case CAM_ISP_HW_VFE_IN_PDLIB:
|
||||
case CAM_ISP_HW_VFE_IN_LCR:
|
||||
case CAM_ISP_HW_VFE_IN_RD:
|
||||
break;
|
||||
default:
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d",
|
||||
|
|
@ -6810,6 +6927,8 @@ static int cam_ife_hw_mgr_handle_hw_sof(
|
|||
struct cam_isp_hw_sof_event_data sof_done_event_data;
|
||||
int rc = 0;
|
||||
|
||||
memset(&sof_done_event_data, 0, sizeof(sof_done_event_data));
|
||||
|
||||
ife_hw_irq_sof_cb =
|
||||
ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_SOF];
|
||||
|
||||
|
|
@ -6820,10 +6939,15 @@ static int cam_ife_hw_mgr_handle_hw_sof(
|
|||
rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(ife_hw_mgr_ctx,
|
||||
CAM_ISP_HW_EVENT_SOF);
|
||||
if (!rc) {
|
||||
cam_ife_mgr_cmd_get_sof_timestamp(
|
||||
ife_hw_mgr_ctx,
|
||||
&sof_done_event_data.timestamp,
|
||||
&sof_done_event_data.boot_time);
|
||||
if (ife_hw_mgr_ctx->is_offline)
|
||||
cam_ife_hw_mgr_get_offline_sof_timestamp(
|
||||
&sof_done_event_data.timestamp,
|
||||
&sof_done_event_data.boot_time);
|
||||
else
|
||||
cam_ife_mgr_cmd_get_sof_timestamp(
|
||||
ife_hw_mgr_ctx,
|
||||
&sof_done_event_data.timestamp,
|
||||
&sof_done_event_data.boot_time);
|
||||
|
||||
/* if frame header is enabled reset qtimer ts */
|
||||
if (ife_hw_mgr_ctx->use_frame_header_ts)
|
||||
|
|
|
|||
|
|
@ -82,12 +82,13 @@ struct cam_ife_hw_mgr_debug {
|
|||
* @last_dump_flush_req_id Last req id for which reg dump on flush was called
|
||||
* @last_dump_err_req_id Last req id for which reg dump on error was called
|
||||
* @init_done indicate whether init hw is done
|
||||
* @is_fe_enable indicate whether fetch engine\read path is enabled
|
||||
* @is_fe_enabled Indicate whether fetch engine\read path is enabled
|
||||
* @is_dual indicate whether context is in dual VFE mode
|
||||
* @custom_enabled update the flag if context is connected to custom HW
|
||||
* @use_frame_header_ts obtain qtimer ts using frame header
|
||||
* @ts captured timestamp when the ctx is acquired
|
||||
* @is_tpg indicate whether context is using PHY TPG
|
||||
* @is_offline Indicate whether context is for offline IFE
|
||||
*/
|
||||
struct cam_ife_hw_mgr_ctx {
|
||||
struct list_head list;
|
||||
|
|
@ -133,12 +134,13 @@ struct cam_ife_hw_mgr_ctx {
|
|||
uint64_t last_dump_flush_req_id;
|
||||
uint64_t last_dump_err_req_id;
|
||||
bool init_done;
|
||||
bool is_fe_enable;
|
||||
bool is_fe_enabled;
|
||||
bool is_dual;
|
||||
bool custom_enabled;
|
||||
bool use_frame_header_ts;
|
||||
struct timespec64 ts;
|
||||
bool is_tpg;
|
||||
bool is_offline;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -947,7 +947,7 @@ int cam_isp_add_reg_update(
|
|||
return rc;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Reg update added for res %d hw_id %d",
|
||||
res->res_id, res->hw_intf->hw_idx);
|
||||
res->res_type, res->hw_intf->hw_idx);
|
||||
reg_update_size += get_regup.cmd.used_bytes;
|
||||
}
|
||||
}
|
||||
|
|
@ -981,3 +981,100 @@ int cam_isp_add_reg_update(
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_isp_add_go_cmd(
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct list_head *res_list_isp_rd,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_hw_update_entry *hw_entry;
|
||||
struct cam_isp_hw_get_cmd_update get_regup;
|
||||
uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size;
|
||||
|
||||
hw_entry = prepare->hw_update_entries;
|
||||
if (prepare->num_hw_update_entries + 1 >=
|
||||
prepare->max_hw_update_entries) {
|
||||
CAM_ERR(CAM_ISP, "Insufficient HW entries current: %d max: %d",
|
||||
prepare->num_hw_update_entries,
|
||||
prepare->max_hw_update_entries);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg_update_size = 0;
|
||||
list_for_each_entry(hw_mgr_res, res_list_isp_rd, list) {
|
||||
if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (!hw_mgr_res->hw_res[i])
|
||||
continue;
|
||||
|
||||
res = hw_mgr_res->hw_res[i];
|
||||
if (res->hw_intf->hw_idx != base_idx)
|
||||
continue;
|
||||
|
||||
if (kmd_buf_info->size > (kmd_buf_info->used_bytes +
|
||||
reg_update_size)) {
|
||||
kmd_buf_remain_size = kmd_buf_info->size -
|
||||
(kmd_buf_info->used_bytes +
|
||||
reg_update_size);
|
||||
} else {
|
||||
CAM_ERR(CAM_ISP, "no free mem %d %d %d",
|
||||
base_idx, kmd_buf_info->size,
|
||||
kmd_buf_info->used_bytes +
|
||||
reg_update_size);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
get_regup.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
|
||||
kmd_buf_info->used_bytes/4 +
|
||||
reg_update_size/4;
|
||||
get_regup.cmd.size = kmd_buf_remain_size;
|
||||
get_regup.cmd_type = CAM_ISP_HW_CMD_FE_TRIGGER_CMD;
|
||||
get_regup.res = res;
|
||||
|
||||
rc = res->process_cmd(res->res_priv,
|
||||
CAM_ISP_HW_CMD_FE_TRIGGER_CMD, &get_regup,
|
||||
sizeof(struct cam_isp_hw_get_cmd_update));
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
CAM_DBG(CAM_ISP, "GO_CMD added for RD res %d hw_id %d",
|
||||
res->res_type, res->hw_intf->hw_idx);
|
||||
reg_update_size += get_regup.cmd.used_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (reg_update_size) {
|
||||
/* Update the HW entries */
|
||||
num_ent = prepare->num_hw_update_entries;
|
||||
prepare->hw_update_entries[num_ent].handle =
|
||||
kmd_buf_info->handle;
|
||||
prepare->hw_update_entries[num_ent].len = reg_update_size;
|
||||
prepare->hw_update_entries[num_ent].offset =
|
||||
kmd_buf_info->offset;
|
||||
|
||||
prepare->hw_update_entries[num_ent].flags =
|
||||
CAM_ISP_IOCFG_BL;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"num_ent=%d handle=0x%x, len=%u, offset=%u",
|
||||
num_ent,
|
||||
prepare->hw_update_entries[num_ent].handle,
|
||||
prepare->hw_update_entries[num_ent].len,
|
||||
prepare->hw_update_entries[num_ent].offset);
|
||||
num_ent++;
|
||||
|
||||
kmd_buf_info->used_bytes += reg_update_size;
|
||||
kmd_buf_info->offset += reg_update_size;
|
||||
prepare->num_hw_update_entries = num_ent;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,4 +176,23 @@ int cam_isp_add_reg_update(
|
|||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info);
|
||||
|
||||
/*
|
||||
* cam_isp_add_go_cmd()
|
||||
*
|
||||
* @brief Add go_cmd in the hw entries list for each rd source
|
||||
*
|
||||
* @prepare: Contain the packet and HW update variables
|
||||
* @res_list_isp_rd: Resource list for BUS RD ports
|
||||
* @base_idx: Base or dev index of the IFE/VFE HW instance
|
||||
* @kmd_buf_info: Kmd buffer to store the change base command
|
||||
* @return: 0 for success
|
||||
* -EINVAL for Fail
|
||||
*/
|
||||
int cam_isp_add_go_cmd(
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct list_head *res_list_isp_rd,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info);
|
||||
|
||||
|
||||
#endif /*_CAM_ISP_HW_PARSER_H */
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ enum cam_isp_ctx_type {
|
|||
CAM_ISP_CTX_FS2 = 1,
|
||||
CAM_ISP_CTX_RDI,
|
||||
CAM_ISP_CTX_PIX,
|
||||
CAM_ISP_CTX_OFFLINE,
|
||||
CAM_ISP_CTX_MAX,
|
||||
};
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ struct cam_isp_in_port_generic_info {
|
|||
uint32_t batch_size;
|
||||
uint32_t dsp_mode;
|
||||
uint32_t hbi_cnt;
|
||||
uint32_t fe_unpacker_fmt;
|
||||
uint32_t cust_node;
|
||||
uint32_t num_out_res;
|
||||
uint32_t horizontal_bin;
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ enum cam_isp_resource_type {
|
|||
CAM_ISP_RESOURCE_CID,
|
||||
CAM_ISP_RESOURCE_PIX_PATH,
|
||||
CAM_ISP_RESOURCE_VFE_IN,
|
||||
CAM_ISP_RESOURCE_VFE_OUT,
|
||||
CAM_ISP_RESOURCE_VFE_BUS_RD,
|
||||
CAM_ISP_RESOURCE_VFE_OUT,
|
||||
CAM_ISP_RESOURCE_TPG,
|
||||
CAM_ISP_RESOURCE_TFE_IN,
|
||||
CAM_ISP_RESOURCE_TFE_OUT,
|
||||
|
|
@ -114,6 +114,7 @@ enum cam_isp_hw_cmd_type {
|
|||
CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE,
|
||||
CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
|
||||
CAM_ISP_HW_CMD_DUMP_HW,
|
||||
CAM_ISP_HW_CMD_FE_TRIGGER_CMD,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,27 @@ struct cam_vfe_hw_get_hw_cap {
|
|||
uint32_t max_rdi_num;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_vfe_hw_vfe_bus_rd_acquire_args:
|
||||
*
|
||||
* @rsrc_node: Pointer to Resource Node object, filled if acquire
|
||||
* is successful
|
||||
* @res_id: Unique Identity of port to associate with this
|
||||
* resource.
|
||||
* @is_dual: Flag to indicate dual VFE usecase
|
||||
* @cdm_ops: CDM operations
|
||||
* @unpacket_fmt: Unpacker format for read engine
|
||||
* @is_offline: Flag to indicate offline usecase
|
||||
*/
|
||||
struct cam_vfe_hw_vfe_bus_rd_acquire_args {
|
||||
struct cam_isp_resource_node *rsrc_node;
|
||||
uint32_t res_id;
|
||||
uint32_t is_dual;
|
||||
struct cam_cdm_utils_ops *cdm_ops;
|
||||
uint32_t unpacker_fmt;
|
||||
bool is_offline;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_vfe_hw_vfe_out_acquire_args:
|
||||
*
|
||||
|
|
@ -143,6 +164,8 @@ struct cam_vfe_hw_vfe_out_acquire_args {
|
|||
* @sync_mode: In case of Dual VFE, this is Master or Slave.
|
||||
* (Default is Master in case of Single VFE)
|
||||
* @in_port: Input port details to acquire
|
||||
* @is_fe_enabled: Flag to indicate if FE is enabled
|
||||
* @is_offline: Flag to indicate Offline IFE
|
||||
*/
|
||||
struct cam_vfe_hw_vfe_in_acquire_args {
|
||||
struct cam_isp_resource_node *rsrc_node;
|
||||
|
|
@ -152,6 +175,8 @@ struct cam_vfe_hw_vfe_in_acquire_args {
|
|||
void *cdm_ops;
|
||||
enum cam_isp_hw_sync_mode sync_mode;
|
||||
struct cam_isp_in_port_generic_info *in_port;
|
||||
bool is_fe_enabled;
|
||||
bool is_offline;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -173,9 +198,9 @@ struct cam_vfe_acquire_args {
|
|||
void *priv;
|
||||
cam_hw_mgr_event_cb_func event_cb;
|
||||
union {
|
||||
struct cam_vfe_hw_vfe_out_acquire_args vfe_out;
|
||||
struct cam_vfe_hw_vfe_out_acquire_args vfe_bus_rd;
|
||||
struct cam_vfe_hw_vfe_in_acquire_args vfe_in;
|
||||
struct cam_vfe_hw_vfe_out_acquire_args vfe_out;
|
||||
struct cam_vfe_hw_vfe_bus_rd_acquire_args vfe_bus_rd;
|
||||
struct cam_vfe_hw_vfe_in_acquire_args vfe_in;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -407,6 +407,7 @@ static struct cam_vfe_bus_rd_ver1_hw_info vfe175_130_bus_rd_hw_info = {
|
|||
.max_height = -1,
|
||||
},
|
||||
},
|
||||
.top_irq_shift = 23,
|
||||
};
|
||||
|
||||
static struct cam_vfe_bus_ver2_hw_info vfe175_130_bus_hw_info = {
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,7 @@ static struct cam_vfe_bus_rd_ver1_hw_info vfe480_bus_rd_hw_info = {
|
|||
.max_height = -1,
|
||||
},
|
||||
},
|
||||
.top_irq_shift = 8,
|
||||
};
|
||||
|
||||
struct cam_vfe_hw_info cam_vfe480_hw_info = {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_VFE_BUS_R_VER1_H_
|
||||
|
|
@ -88,6 +88,7 @@ struct cam_vfe_bus_rd_ver1_hw_info {
|
|||
uint32_t num_bus_rd_resc;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_hw_info
|
||||
vfe_bus_rd_hw_info[CAM_VFE_BUS_RD_VER1_VFE_BUSRD_MAX];
|
||||
uint32_t top_irq_shift;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ struct cam_vfe_mux_camif_ver3_data {
|
|||
uint32_t qcfa_bin;
|
||||
uint32_t dual_hw_idx;
|
||||
uint32_t is_dual;
|
||||
bool is_fe_enabled;
|
||||
bool is_offline;
|
||||
};
|
||||
|
||||
static int cam_vfe_camif_ver3_get_evt_payload(
|
||||
|
|
@ -248,19 +250,20 @@ int cam_vfe_camif_ver3_acquire_resource(
|
|||
return rc;
|
||||
}
|
||||
|
||||
camif_data->sync_mode = acquire_data->vfe_in.sync_mode;
|
||||
camif_data->pix_pattern = acquire_data->vfe_in.in_port->test_pattern;
|
||||
camif_data->dsp_mode = acquire_data->vfe_in.in_port->dsp_mode;
|
||||
camif_data->first_pixel = acquire_data->vfe_in.in_port->left_start;
|
||||
camif_data->last_pixel = acquire_data->vfe_in.in_port->left_stop;
|
||||
camif_data->first_line = acquire_data->vfe_in.in_port->line_start;
|
||||
camif_data->last_line = acquire_data->vfe_in.in_port->line_stop;
|
||||
camif_data->sync_mode = acquire_data->vfe_in.sync_mode;
|
||||
camif_data->pix_pattern = acquire_data->vfe_in.in_port->test_pattern;
|
||||
camif_data->dsp_mode = acquire_data->vfe_in.in_port->dsp_mode;
|
||||
camif_data->first_pixel = acquire_data->vfe_in.in_port->left_start;
|
||||
camif_data->last_pixel = acquire_data->vfe_in.in_port->left_stop;
|
||||
camif_data->first_line = acquire_data->vfe_in.in_port->line_start;
|
||||
camif_data->last_line = acquire_data->vfe_in.in_port->line_stop;
|
||||
camif_data->is_fe_enabled = acquire_data->vfe_in.is_fe_enabled;
|
||||
camif_data->is_offline = acquire_data->vfe_in.is_offline;
|
||||
camif_data->event_cb = acquire_data->event_cb;
|
||||
camif_data->priv = acquire_data->priv;
|
||||
camif_data->qcfa_bin = acquire_data->vfe_in.in_port->qcfa_bin;
|
||||
camif_data->horizontal_bin =
|
||||
acquire_data->vfe_in.in_port->horizontal_bin;
|
||||
camif_data->qcfa_bin = acquire_data->vfe_in.in_port->qcfa_bin;
|
||||
camif_data->event_cb = acquire_data->event_cb;
|
||||
camif_data->priv = acquire_data->priv;
|
||||
camif_data->is_dual = acquire_data->vfe_in.is_dual;
|
||||
|
||||
if (acquire_data->vfe_in.is_dual)
|
||||
camif_data->dual_hw_idx = acquire_data->vfe_in.dual_hw_idx;
|
||||
|
|
@ -417,12 +420,20 @@ static int cam_vfe_camif_ver3_resource_start(
|
|||
val |= (rsrc_data->cam_common_cfg.input_mux_sel_pp & 0x3) <<
|
||||
CAM_SHIFT_TOP_CORE_CFG_INPUTMUX_PP;
|
||||
|
||||
if (rsrc_data->is_fe_enabled && !rsrc_data->is_offline)
|
||||
val |= 0x2 << rsrc_data->reg_data->operating_mode_shift;
|
||||
else
|
||||
val |= 0x1 << rsrc_data->reg_data->operating_mode_shift;
|
||||
|
||||
if (rsrc_data->is_dual && rsrc_data->reg_data->dual_vfe_sync_mask) {
|
||||
val |= (((rsrc_data->dual_hw_idx &
|
||||
rsrc_data->reg_data->dual_vfe_sync_mask) + 1) <<
|
||||
rsrc_data->reg_data->dual_ife_sync_sel_shift);
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "VFE:%d TOP core_cfg: 0x%X",
|
||||
camif_res->hw_intf->hw_idx, val);
|
||||
|
||||
cam_io_w_mb(val, rsrc_data->mem_base +
|
||||
rsrc_data->common_reg->core_cfg_0);
|
||||
|
||||
|
|
@ -459,11 +470,14 @@ static int cam_vfe_camif_ver3_resource_start(
|
|||
camif_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
|
||||
/* Reg Update */
|
||||
cam_io_w_mb(rsrc_data->reg_data->reg_update_cmd_data,
|
||||
rsrc_data->mem_base + rsrc_data->camif_reg->reg_update_cmd);
|
||||
CAM_DBG(CAM_ISP, "VFE:%d CAMIF RUP val:0x%X",
|
||||
camif_res->hw_intf->hw_idx,
|
||||
rsrc_data->reg_data->reg_update_cmd_data);
|
||||
if (!rsrc_data->is_offline) {
|
||||
cam_io_w_mb(rsrc_data->reg_data->reg_update_cmd_data,
|
||||
rsrc_data->mem_base +
|
||||
rsrc_data->camif_reg->reg_update_cmd);
|
||||
CAM_DBG(CAM_ISP, "VFE:%d CAMIF RUP val:0x%X",
|
||||
camif_res->hw_intf->hw_idx,
|
||||
rsrc_data->reg_data->reg_update_cmd_data);
|
||||
}
|
||||
|
||||
/* disable sof irq debug flag */
|
||||
rsrc_data->enable_sof_irq_debug = false;
|
||||
|
|
@ -606,6 +620,18 @@ static int cam_vfe_camif_ver3_reg_dump(
|
|||
CAM_INFO(CAM_ISP, "offset 0x%X value 0x%X", offset, val);
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_ISP, "IFE:%d BUS RD", camif_res->hw_intf->hw_idx);
|
||||
for (offset = 0xA800; offset <= 0xA89C; offset += 0x4) {
|
||||
val = cam_soc_util_r(camif_priv->soc_info, 0, offset);
|
||||
CAM_INFO(CAM_ISP, "offset 0x%X value 0x%X", offset, val);
|
||||
if (offset == 0xA838)
|
||||
offset = 0xA844;
|
||||
if (offset == 0xA864)
|
||||
offset = 0xA874;
|
||||
if (offset == 0xA878)
|
||||
offset = 0xA87C;
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_ISP, "IFE:%d BUS WR", camif_res->hw_intf->hw_idx);
|
||||
for (offset = 0xAA00; offset <= 0xAADC; offset += 0x4) {
|
||||
val = cam_soc_util_r(camif_priv->soc_info, 0, offset);
|
||||
|
|
|
|||
Loading…
Reference in a new issue