msm: camera: isp: Add support for offline IFE
This change adds new IRQ state machine and updates the acquire logic to enable offline IFE. This change also adds the fixes necessary to enable bus read for various buffer formats and append go command at the end of each packet for offline context. CRs-Fixed: 2513939 Change-Id: Ie068670ed11aa6713e8f0cb817e4b5d4c209e696 Signed-off-by: Venkat Chinta <vchinta@codeaurora.org>
This commit is contained in:
@@ -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:
|
||||
@@ -3832,6 +3994,10 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
|
||||
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 =
|
||||
@@ -3990,6 +4156,11 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx,
|
||||
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 =
|
||||
@@ -4141,6 +4312,12 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
|
||||
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,9 +2118,9 @@ 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))
|
||||
@@ -2333,7 +2135,6 @@ static int cam_ife_hw_mgr_preprocess_port(
|
||||
ipp_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ipp_count = ipp_num;
|
||||
*rdi_count = rdi_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,11 +2714,13 @@ 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) {
|
||||
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++) {
|
||||
port_info->vc[i] = in->vc[i];
|
||||
@@ -2659,6 +2742,7 @@ static int cam_ife_mgr_acquire_get_unified_structure_v2(
|
||||
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;
|
||||
@@ -2822,6 +2906,13 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
goto free_mem;
|
||||
}
|
||||
|
||||
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],
|
||||
@@ -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,10 +4194,20 @@ 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;
|
||||
}
|
||||
@@ -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,6 +6939,11 @@ 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) {
|
||||
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,
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -174,7 +199,7 @@ struct cam_vfe_acquire_args {
|
||||
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_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 = {
|
||||
|
@@ -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.
|
||||
*/
|
||||
|
||||
#include <linux/ratelimit.h>
|
||||
@@ -39,24 +39,29 @@ static const char drv_name[] = "vfe_bus_rd";
|
||||
buf_array[(index)++] = val; \
|
||||
} while (0)
|
||||
|
||||
#define BUS_RD_VER1_DEFAULT_LATENCY_BUF_ALLOC 512
|
||||
|
||||
enum cam_vfe_bus_rd_ver1_unpacker_format {
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_128 = 0x0,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_8 = 0x1,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_16_10BPP = 0x2,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_16_12BPP = 0x3,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_16_14BPP = 0x4,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_16_16BPP = 0x5,
|
||||
BUS_RD_VER1_PACKER_FMT_ARGB_10 = 0x6,
|
||||
BUS_RD_VER1_PACKER_FMT_ARGB_12 = 0x7,
|
||||
BUS_RD_VER1_PACKER_FMT_ARGB_14 = 0x8,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_32_20BPP = 0x9,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_64 = 0xA,
|
||||
BUS_RD_VER1_PACKER_FMT_TP_10 = 0xB,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_32_32BPP = 0xC,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_8_ODD_EVEN = 0xD,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_8_LSB_MSB_10 = 0xE,
|
||||
BUS_RD_VER1_PACKER_FMT_PLAIN_8_LSB_MSB_10_ODD_EVEN = 0xF,
|
||||
BUS_RD_VER1_PACKER_FMT_MAX = 0xF,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_128 = 0x0,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_8 = 0x1,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_10BPP = 0x2,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_12BPP = 0x3,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_14BPP = 0x4,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_32_20BPP = 0x5,
|
||||
BUS_RD_VER1_UNPACKER_FMT_ARGB_10 = 0x6,
|
||||
BUS_RD_VER1_UNPACKER_FMT_ARGB_12 = 0x7,
|
||||
BUS_RD_VER1_UNPACKER_FMT_ARGB_14 = 0x8,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_32 = 0x9,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_64 = 0xA,
|
||||
BUS_RD_VER1_UNPACKER_FMT_TP_10 = 0xB,
|
||||
BUS_RD_VER1_UNPACKER_FMT_MIPI8 = 0xC,
|
||||
BUS_RD_VER1_UNPACKER_FMT_MIPI10 = 0xD,
|
||||
BUS_RD_VER1_UNPACKER_FMT_MIPI12 = 0xE,
|
||||
BUS_RD_VER1_UNPACKER_FMT_MIPI14 = 0xF,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_16BPP = 0x10,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_128_ODD_EVEN = 0x11,
|
||||
BUS_RD_VER1_UNPACKER_FMT_PLAIN_8_ODD_EVEN = 0x12,
|
||||
BUS_RD_VER1_UNPACKER_FMT_MAX = 0x13,
|
||||
};
|
||||
|
||||
struct cam_vfe_bus_rd_ver1_common_data {
|
||||
@@ -76,6 +81,7 @@ struct cam_vfe_bus_rd_ver1_common_data {
|
||||
uint32_t num_sec_out;
|
||||
uint32_t fs_sync_enable;
|
||||
uint32_t go_cmd_sel;
|
||||
cam_hw_mgr_event_cb_func event_cb;
|
||||
};
|
||||
|
||||
struct cam_vfe_bus_rd_ver1_rm_resource_data {
|
||||
@@ -85,7 +91,6 @@ struct cam_vfe_bus_rd_ver1_rm_resource_data {
|
||||
void *ctx;
|
||||
|
||||
bool init_cfg_done;
|
||||
bool hfr_cfg_done;
|
||||
|
||||
uint32_t offset;
|
||||
|
||||
@@ -127,6 +132,10 @@ struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data {
|
||||
uint32_t max_height;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||
uint32_t secure_mode;
|
||||
int irq_handle;
|
||||
void *priv;
|
||||
uint32_t status;
|
||||
bool is_offline;
|
||||
};
|
||||
|
||||
struct cam_vfe_bus_rd_ver1_priv {
|
||||
@@ -140,32 +149,105 @@ struct cam_vfe_bus_rd_ver1_priv {
|
||||
CAM_VFE_BUS_RD_VER1_VFE_BUSRD_MAX];
|
||||
|
||||
int irq_handle;
|
||||
int error_irq_handle;
|
||||
void *tasklet_info;
|
||||
uint32_t top_irq_shift;
|
||||
};
|
||||
|
||||
static int cam_vfe_bus_process_cmd(
|
||||
static int cam_vfe_bus_rd_process_cmd(
|
||||
struct cam_isp_resource_node *priv,
|
||||
uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
|
||||
|
||||
static void cam_vfe_bus_rd_pxls_to_bytes(uint32_t pxls, uint32_t fmt,
|
||||
uint32_t *bytes)
|
||||
{
|
||||
switch (fmt) {
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_128:
|
||||
*bytes = pxls * 16;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_8:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_8_ODD_EVEN:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_10BPP:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_12BPP:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_14BPP:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_16BPP:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_ARGB_10:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_ARGB_12:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_ARGB_14:
|
||||
*bytes = pxls * 2;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_32_20BPP:
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_32:
|
||||
*bytes = pxls * 4;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_PLAIN_64:
|
||||
*bytes = pxls * 8;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_TP_10:
|
||||
*bytes = ALIGNUP(pxls, 3) * 4 / 3;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_MIPI8:
|
||||
*bytes = pxls;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_MIPI10:
|
||||
*bytes = ALIGNUP(pxls * 5, 4) / 4;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_MIPI12:
|
||||
*bytes = ALIGNUP(pxls * 3, 2) / 2;
|
||||
break;
|
||||
case BUS_RD_VER1_UNPACKER_FMT_MIPI14:
|
||||
*bytes = ALIGNUP(pxls * 7, 4) / 4;
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "Invalid unpacker_fmt:%d", fmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static enum cam_vfe_bus_rd_ver1_unpacker_format
|
||||
cam_vfe_bus_get_unpacker_fmt(uint32_t unpack_fmt)
|
||||
{
|
||||
switch (unpack_fmt) {
|
||||
case CAM_FORMAT_PLAIN128:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_128;
|
||||
case CAM_FORMAT_PLAIN8:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_8;
|
||||
case CAM_FORMAT_PLAIN16_10:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_10BPP;
|
||||
case CAM_FORMAT_PLAIN16_12:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_12BPP;
|
||||
case CAM_FORMAT_PLAIN16_14:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_14BPP;
|
||||
case CAM_FORMAT_PLAIN32_20:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_32_20BPP;
|
||||
case CAM_FORMAT_ARGB_10:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_ARGB_10;
|
||||
case CAM_FORMAT_ARGB_12:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_ARGB_12;
|
||||
case CAM_FORMAT_ARGB_14:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_ARGB_14;
|
||||
case CAM_FORMAT_PLAIN32:
|
||||
case CAM_FORMAT_ARGB:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_32;
|
||||
case CAM_FORMAT_PLAIN64:
|
||||
case CAM_FORMAT_ARGB_16:
|
||||
case CAM_FORMAT_PD10:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_64;
|
||||
case CAM_FORMAT_TP10:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_TP_10;
|
||||
case CAM_FORMAT_MIPI_RAW_8:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_MIPI8;
|
||||
case CAM_FORMAT_MIPI_RAW_10:
|
||||
return BUS_RD_VER1_PACKER_FMT_PLAIN_8_ODD_EVEN;
|
||||
return BUS_RD_VER1_UNPACKER_FMT_MIPI10;
|
||||
case CAM_FORMAT_MIPI_RAW_12:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_MIPI12;
|
||||
case CAM_FORMAT_MIPI_RAW_14:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_MIPI14;
|
||||
case CAM_FORMAT_PLAIN16_16:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_16_16BPP;
|
||||
case CAM_FORMAT_PLAIN8_SWAP:
|
||||
return BUS_RD_VER1_UNPACKER_FMT_PLAIN_8_ODD_EVEN;
|
||||
default:
|
||||
return BUS_RD_VER1_PACKER_FMT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static bool cam_vfe_bus_can_be_secure(uint32_t out_type)
|
||||
{
|
||||
switch (out_type) {
|
||||
case CAM_VFE_BUS_RD_VER1_VFE_BUSRD_RDI0:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
return BUS_RD_VER1_UNPACKER_FMT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,12 +269,58 @@ static int cam_vfe_bus_get_num_rm(
|
||||
case CAM_VFE_BUS_RD_VER1_VFE_BUSRD_RDI0:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
CAM_ERR(CAM_ISP, "Unsupported resource_type %u", res_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
CAM_ERR(CAM_ISP, "Unsupported resource_type %u",
|
||||
res_type);
|
||||
return -EINVAL;
|
||||
static int cam_vfe_bus_rd_handle_irq_top_half(uint32_t evt_id,
|
||||
struct cam_irq_th_payload *th_payload)
|
||||
{
|
||||
struct cam_isp_resource_node *bus_rd = NULL;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rsrc_data = NULL;
|
||||
|
||||
bus_rd = th_payload->handler_priv;
|
||||
if (!bus_rd) {
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "No resource");
|
||||
return -ENODEV;
|
||||
}
|
||||
rsrc_data = bus_rd->res_priv;
|
||||
rsrc_data->status = th_payload->evt_status_arr[0];
|
||||
|
||||
CAM_DBG(CAM_ISP, "VFE:%d Bus RD IRQ status_0: 0x%X",
|
||||
rsrc_data->common_data->core_index,
|
||||
th_payload->evt_status_arr[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_rd_handle_irq_bottom_half(
|
||||
void *handler_priv, void *evt_payload_priv)
|
||||
{
|
||||
struct cam_isp_resource_node *bus_rd = NULL;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rsrc_data = NULL;
|
||||
|
||||
bus_rd = (struct cam_isp_resource_node *)handler_priv;
|
||||
if (!bus_rd) {
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "No resource");
|
||||
return -ENODEV;
|
||||
}
|
||||
rsrc_data = bus_rd->res_priv;
|
||||
|
||||
if (rsrc_data->status & 0x2)
|
||||
CAM_DBG(CAM_ISP, "Received VFE:%d BUS RD RUP",
|
||||
rsrc_data->common_data->core_index);
|
||||
else if (rsrc_data->status & 0x4)
|
||||
CAM_DBG(CAM_ISP, "Received VFE:%d BUS RD BUF DONE",
|
||||
rsrc_data->common_data->core_index);
|
||||
else if (rsrc_data->status & 0x10000) {
|
||||
CAM_ERR(CAM_ISP, "Received VFE:%d BUS RD CCIF Violation",
|
||||
rsrc_data->common_data->core_index);
|
||||
return CAM_VFE_IRQ_STATUS_VIOLATION;
|
||||
}
|
||||
|
||||
return CAM_VFE_IRQ_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_get_rm_idx(
|
||||
@@ -220,15 +348,14 @@ static int cam_vfe_bus_get_rm_idx(
|
||||
|
||||
static int cam_vfe_bus_acquire_rm(
|
||||
struct cam_vfe_bus_rd_ver1_priv *ver1_bus_rd_priv,
|
||||
struct cam_isp_out_port_generic_info *out_port_info,
|
||||
void *tasklet,
|
||||
void *ctx,
|
||||
enum cam_vfe_bus_rd_ver1_vfe_bus_rd_type vfe_bus_rd_res_id,
|
||||
enum cam_vfe_bus_plane_type plane,
|
||||
uint32_t subscribe_irq,
|
||||
struct cam_isp_resource_node **rm_res,
|
||||
uint32_t *client_done_mask,
|
||||
uint32_t is_dual)
|
||||
uint32_t is_dual,
|
||||
uint32_t unpacker_fmt)
|
||||
{
|
||||
uint32_t rm_idx = 0;
|
||||
struct cam_isp_resource_node *rm_res_local = NULL;
|
||||
@@ -240,14 +367,15 @@ static int cam_vfe_bus_acquire_rm(
|
||||
/* No need to allocate for BUS VER2. VFE OUT to RM is fixed. */
|
||||
rm_idx = cam_vfe_bus_get_rm_idx(vfe_bus_rd_res_id, plane);
|
||||
if (rm_idx < 0 || rm_idx >= ver1_bus_rd_priv->num_client) {
|
||||
CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
|
||||
CAM_ERR(CAM_ISP, "Unsupported VFE RM:%d plane:%d",
|
||||
vfe_bus_rd_res_id, plane);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rm_res_local = &ver1_bus_rd_priv->bus_client[rm_idx];
|
||||
if (rm_res_local->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
|
||||
CAM_ERR(CAM_ISP, "RM res not available state:%d",
|
||||
CAM_ERR(CAM_ISP, "VFE:%d RM:%d res not available state:%d",
|
||||
ver1_bus_rd_priv->common_data.core_index, rm_idx,
|
||||
rm_res_local->res_state);
|
||||
return -EALREADY;
|
||||
}
|
||||
@@ -257,13 +385,17 @@ static int cam_vfe_bus_acquire_rm(
|
||||
rsrc_data = rm_res_local->res_priv;
|
||||
rsrc_data->ctx = ctx;
|
||||
rsrc_data->is_dual = is_dual;
|
||||
rsrc_data->unpacker_cfg = cam_vfe_bus_get_unpacker_fmt(unpacker_fmt);
|
||||
rsrc_data->latency_buf_allocation =
|
||||
BUS_RD_VER1_DEFAULT_LATENCY_BUF_ALLOC;
|
||||
/* Set RM offset value to default */
|
||||
rsrc_data->offset = 0;
|
||||
|
||||
*client_done_mask = (1 << rm_idx);
|
||||
*client_done_mask = (1 << (rm_idx + 2));
|
||||
*rm_res = rm_res_local;
|
||||
|
||||
CAM_DBG(CAM_ISP, "RM %d: Acquired");
|
||||
CAM_DBG(CAM_ISP, "VFE:%d RM:%d Acquired",
|
||||
rsrc_data->common_data->core_index, rsrc_data->index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -281,68 +413,49 @@ static int cam_vfe_bus_release_rm(void *bus_priv,
|
||||
rsrc_data->unpacker_cfg = 0;
|
||||
rsrc_data->burst_len = 0;
|
||||
rsrc_data->init_cfg_done = false;
|
||||
rsrc_data->hfr_cfg_done = false;
|
||||
rsrc_data->en_cfg = 0;
|
||||
rsrc_data->is_dual = 0;
|
||||
|
||||
rm_res->tasklet_info = NULL;
|
||||
rm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
||||
|
||||
CAM_DBG(CAM_ISP, "VFE:%d RM:%d released",
|
||||
rsrc_data->common_data->core_index, rsrc_data->index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_start_rm(struct cam_isp_resource_node *rm_res)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_vfe_bus_rd_ver1_rm_resource_data *rm_data =
|
||||
rm_res->res_priv;
|
||||
struct cam_vfe_bus_rd_ver1_common_data *common_data =
|
||||
rm_data->common_data;
|
||||
struct cam_vfe_bus_rd_ver1_rm_resource_data *rm_data;
|
||||
struct cam_vfe_bus_rd_ver1_common_data *common_data;
|
||||
uint32_t buf_size;
|
||||
uint32_t val;
|
||||
uint32_t offset;
|
||||
|
||||
CAM_DBG(CAM_ISP, "w: 0x%x", rm_data->width);
|
||||
CAM_DBG(CAM_ISP, "h: 0x%x", rm_data->height);
|
||||
CAM_DBG(CAM_ISP, "format: 0x%x", rm_data->format);
|
||||
CAM_DBG(CAM_ISP, "unpacker_cfg: 0x%x", rm_data->unpacker_cfg);
|
||||
CAM_DBG(CAM_ISP, "latency_buf_allocation: 0x%x",
|
||||
rm_data->latency_buf_allocation);
|
||||
CAM_DBG(CAM_ISP, "stride: 0x%x", rm_data->stride);
|
||||
CAM_DBG(CAM_ISP, "go_cmd_sel: 0x%x", rm_data->go_cmd_sel);
|
||||
CAM_DBG(CAM_ISP, "fs_sync_enable: 0x%x", rm_data->fs_sync_enable);
|
||||
CAM_DBG(CAM_ISP, "hbi_count: 0x%x", rm_data->hbi_count);
|
||||
CAM_DBG(CAM_ISP, "fs_line_sync_en: 0x%x", rm_data->fs_line_sync_en);
|
||||
CAM_DBG(CAM_ISP, "fs_mode: 0x%x", rm_data->fs_mode);
|
||||
CAM_DBG(CAM_ISP, "min_vbi: 0x%x", rm_data->min_vbi);
|
||||
rm_data = rm_res->res_priv;
|
||||
common_data = rm_data->common_data;
|
||||
|
||||
/* Write All the values*/
|
||||
offset = rm_data->hw_regs->buf_size;
|
||||
buf_size = ((rm_data->width)&(0x0000FFFF)) |
|
||||
((rm_data->height<<16)&(0xFFFF0000));
|
||||
cam_io_w_mb(buf_size, common_data->mem_base + offset);
|
||||
CAM_DBG(CAM_ISP, "buf_size: 0x%x", buf_size);
|
||||
cam_io_w_mb(buf_size, common_data->mem_base +
|
||||
rm_data->hw_regs->buf_size);
|
||||
cam_io_w_mb(rm_data->width, common_data->mem_base +
|
||||
rm_data->hw_regs->stride);
|
||||
cam_io_w_mb(rm_data->unpacker_cfg, common_data->mem_base +
|
||||
rm_data->hw_regs->unpacker_cfg);
|
||||
cam_io_w_mb(rm_data->latency_buf_allocation, common_data->mem_base +
|
||||
rm_data->hw_regs->latency_buf_allocation);
|
||||
cam_io_w_mb(0x1, common_data->mem_base + rm_data->hw_regs->cfg);
|
||||
|
||||
val = rm_data->width;
|
||||
offset = rm_data->hw_regs->stride;
|
||||
CAM_DBG(CAM_ISP, "offset:0x%x, value:0x%x", offset, val);
|
||||
cam_io_w_mb(val, common_data->mem_base + offset);
|
||||
rm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
|
||||
CAM_DBG(CAM_ISP, "rm_data->unpacker_cfg:0x%x", rm_data->unpacker_cfg);
|
||||
val = cam_vfe_bus_get_unpacker_fmt(rm_data->unpacker_cfg);
|
||||
CAM_DBG(CAM_ISP, " value:0x%x", val);
|
||||
offset = rm_data->hw_regs->unpacker_cfg;
|
||||
CAM_DBG(CAM_ISP, "offset:0x%x, value:0x%x", offset, val);
|
||||
cam_io_w_mb(val, common_data->mem_base + offset);
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Start VFE:%d RM:%d offset:0x%X en_cfg:0x%X width:%d height:%d",
|
||||
rm_data->common_data->core_index, rm_data->index,
|
||||
(uint32_t) rm_data->hw_regs->cfg, rm_data->en_cfg,
|
||||
rm_data->width, rm_data->height);
|
||||
CAM_DBG(CAM_ISP, "RM:%d pk_fmt:%d stride:%d", rm_data->index,
|
||||
rm_data->unpacker_cfg, rm_data->stride);
|
||||
|
||||
val = rm_data->latency_buf_allocation;
|
||||
offset = rm_data->hw_regs->latency_buf_allocation;
|
||||
CAM_DBG(CAM_ISP, "offset:0x%x, value:0x%x", offset, val);
|
||||
cam_io_w_mb(val, common_data->mem_base + offset);
|
||||
|
||||
cam_io_w_mb(0x1, common_data->mem_base +
|
||||
rm_data->hw_regs->cfg);
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_stop_rm(struct cam_isp_resource_node *rm_res)
|
||||
@@ -354,12 +467,13 @@ static int cam_vfe_bus_stop_rm(struct cam_isp_resource_node *rm_res)
|
||||
rsrc_data->common_data;
|
||||
|
||||
/* Disable RM */
|
||||
cam_io_w_mb(0x0,
|
||||
common_data->mem_base + rsrc_data->hw_regs->cfg);
|
||||
cam_io_w_mb(0x0, common_data->mem_base + rsrc_data->hw_regs->cfg);
|
||||
|
||||
rm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
rsrc_data->init_cfg_done = false;
|
||||
rsrc_data->hfr_cfg_done = false;
|
||||
|
||||
CAM_DBG(CAM_ISP, "VFE:%d RM:%d stopped",
|
||||
rsrc_data->common_data->core_index, rsrc_data->index);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -374,7 +488,8 @@ static int cam_vfe_bus_init_rm_resource(uint32_t index,
|
||||
rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_rd_ver1_rm_resource_data),
|
||||
GFP_KERNEL);
|
||||
if (!rsrc_data) {
|
||||
CAM_DBG(CAM_ISP, "Failed to alloc for RM res priv");
|
||||
CAM_DBG(CAM_ISP, "Failed to alloc VFE:%d RM res priv",
|
||||
ver1_bus_rd_priv->common_data.core_index);
|
||||
return -ENOMEM;
|
||||
}
|
||||
rm_res->res_priv = rsrc_data;
|
||||
@@ -390,7 +505,6 @@ static int cam_vfe_bus_init_rm_resource(uint32_t index,
|
||||
rm_res->stop = cam_vfe_bus_stop_rm;
|
||||
rm_res->hw_intf = ver1_bus_rd_priv->common_data.hw_intf;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -430,15 +544,13 @@ static int cam_vfe_bus_acquire_vfe_bus_rd(void *bus_priv, void *acquire_args,
|
||||
int i;
|
||||
enum cam_vfe_bus_rd_ver1_vfe_bus_rd_type bus_rd_res_id;
|
||||
int num_rm;
|
||||
uint32_t subscribe_irq;
|
||||
uint32_t client_done_mask;
|
||||
struct cam_vfe_bus_rd_ver1_priv *ver1_bus_rd_priv =
|
||||
bus_priv;
|
||||
struct cam_vfe_acquire_args *acq_args = acquire_args;
|
||||
struct cam_vfe_hw_vfe_out_acquire_args *bus_rd_acquire_args;
|
||||
struct cam_vfe_hw_vfe_bus_rd_acquire_args *bus_rd_acquire_args;
|
||||
struct cam_isp_resource_node *rsrc_node = NULL;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rsrc_data = NULL;
|
||||
uint32_t secure_caps = 0, mode;
|
||||
|
||||
if (!bus_priv || !acquire_args) {
|
||||
CAM_ERR(CAM_ISP, "Invalid Param");
|
||||
@@ -447,9 +559,6 @@ static int cam_vfe_bus_acquire_vfe_bus_rd(void *bus_priv, void *acquire_args,
|
||||
|
||||
bus_rd_acquire_args = &acq_args->vfe_bus_rd;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
|
||||
acq_args->rsrc_type);
|
||||
|
||||
bus_rd_res_id = cam_vfe_bus_get_bus_rd_res_id(
|
||||
acq_args->rsrc_type);
|
||||
if (bus_rd_res_id == CAM_VFE_BUS_RD_VER1_VFE_BUSRD_MAX)
|
||||
@@ -461,61 +570,40 @@ static int cam_vfe_bus_acquire_vfe_bus_rd(void *bus_priv, void *acquire_args,
|
||||
|
||||
rsrc_node = &ver1_bus_rd_priv->vfe_bus_rd[bus_rd_res_id];
|
||||
if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
|
||||
CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
|
||||
bus_rd_res_id, rsrc_node->res_state);
|
||||
CAM_ERR(CAM_ISP, "VFE:%d RM:0x%x not available state:%d",
|
||||
ver1_bus_rd_priv->common_data.core_index,
|
||||
acq_args->rsrc_type, rsrc_node->res_state);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
rsrc_node->res_id = acq_args->rsrc_type;
|
||||
rsrc_data = rsrc_node->res_priv;
|
||||
secure_caps = cam_vfe_bus_can_be_secure(
|
||||
rsrc_data->bus_rd_type);
|
||||
|
||||
mode = bus_rd_acquire_args->out_port_info->secure_mode;
|
||||
mutex_lock(&rsrc_data->common_data->bus_mutex);
|
||||
if (secure_caps) {
|
||||
if (!rsrc_data->common_data->num_sec_out) {
|
||||
rsrc_data->secure_mode = mode;
|
||||
rsrc_data->common_data->secure_mode = mode;
|
||||
} else {
|
||||
if (mode == rsrc_data->common_data->secure_mode) {
|
||||
rsrc_data->secure_mode =
|
||||
rsrc_data->common_data->secure_mode;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP,
|
||||
"Mismatch: Acquire mode[%d], drvr mode[%d]",
|
||||
rsrc_data->common_data->secure_mode,
|
||||
mode);
|
||||
mutex_unlock(
|
||||
&rsrc_data->common_data->bus_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
rsrc_data->common_data->num_sec_out++;
|
||||
}
|
||||
mutex_unlock(&rsrc_data->common_data->bus_mutex);
|
||||
CAM_DBG(CAM_ISP, "VFE:%d acquire RD type:0x%x",
|
||||
rsrc_data->common_data->core_index, acq_args->rsrc_type);
|
||||
|
||||
rsrc_data->num_rm = num_rm;
|
||||
rsrc_node->tasklet_info = acq_args->tasklet;
|
||||
ver1_bus_rd_priv->tasklet_info = acq_args->tasklet;
|
||||
rsrc_node->cdm_ops = bus_rd_acquire_args->cdm_ops;
|
||||
rsrc_data->cdm_util_ops = bus_rd_acquire_args->cdm_ops;
|
||||
|
||||
subscribe_irq = 1;
|
||||
rsrc_data->common_data->event_cb = acq_args->event_cb;
|
||||
rsrc_data->priv = acq_args->priv;
|
||||
rsrc_data->is_offline = bus_rd_acquire_args->is_offline;
|
||||
|
||||
for (i = 0; i < num_rm; i++) {
|
||||
rc = cam_vfe_bus_acquire_rm(ver1_bus_rd_priv,
|
||||
bus_rd_acquire_args->out_port_info,
|
||||
acq_args->tasklet,
|
||||
acq_args->priv,
|
||||
bus_rd_res_id,
|
||||
i,
|
||||
subscribe_irq,
|
||||
&rsrc_data->rm_res[i],
|
||||
&client_done_mask,
|
||||
bus_rd_acquire_args->is_dual);
|
||||
bus_rd_acquire_args->is_dual,
|
||||
bus_rd_acquire_args->unpacker_fmt);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"VFE%d RM acquire failed for Out %d rc=%d",
|
||||
"VFE:%d RM:%d acquire failed rc:%d",
|
||||
rsrc_data->common_data->core_index,
|
||||
bus_rd_res_id, rc);
|
||||
goto release_rm;
|
||||
@@ -525,7 +613,8 @@ static int cam_vfe_bus_acquire_vfe_bus_rd(void *bus_priv, void *acquire_args,
|
||||
rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
bus_rd_acquire_args->rsrc_node = rsrc_node;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Acquire successful");
|
||||
CAM_DBG(CAM_ISP, "VFE:%d acquire RD 0x%x successful",
|
||||
rsrc_data->common_data->core_index, acq_args->rsrc_type);
|
||||
return rc;
|
||||
|
||||
release_rm:
|
||||
@@ -540,7 +629,6 @@ static int cam_vfe_bus_release_vfe_bus_rd(void *bus_priv, void *release_args,
|
||||
uint32_t i;
|
||||
struct cam_isp_resource_node *vfe_bus_rd = NULL;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rsrc_data = NULL;
|
||||
uint32_t secure_caps = 0;
|
||||
|
||||
if (!bus_priv || !release_args) {
|
||||
CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
|
||||
@@ -552,8 +640,10 @@ static int cam_vfe_bus_release_vfe_bus_rd(void *bus_priv, void *release_args,
|
||||
rsrc_data = vfe_bus_rd->res_priv;
|
||||
|
||||
if (vfe_bus_rd->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
|
||||
CAM_ERR(CAM_ISP, "Invalid resource state:%d",
|
||||
vfe_bus_rd->res_state);
|
||||
CAM_ERR(CAM_ISP,
|
||||
"VFE:%d RD type:0x%x invalid resource state:%d",
|
||||
rsrc_data->common_data->core_index,
|
||||
vfe_bus_rd->res_id, vfe_bus_rd->res_state);
|
||||
}
|
||||
|
||||
for (i = 0; i < rsrc_data->num_rm; i++)
|
||||
@@ -564,32 +654,6 @@ static int cam_vfe_bus_release_vfe_bus_rd(void *bus_priv, void *release_args,
|
||||
vfe_bus_rd->cdm_ops = NULL;
|
||||
rsrc_data->cdm_util_ops = NULL;
|
||||
|
||||
secure_caps = cam_vfe_bus_can_be_secure(rsrc_data->bus_rd_type);
|
||||
mutex_lock(&rsrc_data->common_data->bus_mutex);
|
||||
if (secure_caps) {
|
||||
if (rsrc_data->secure_mode ==
|
||||
rsrc_data->common_data->secure_mode) {
|
||||
rsrc_data->common_data->num_sec_out--;
|
||||
rsrc_data->secure_mode =
|
||||
CAM_SECURE_MODE_NON_SECURE;
|
||||
} else {
|
||||
/*
|
||||
* The validity of the mode is properly
|
||||
* checked while acquiring the output port.
|
||||
* not expected to reach here, unless there is
|
||||
* some corruption.
|
||||
*/
|
||||
CAM_ERR(CAM_ISP, "driver[%d],resource[%d] mismatch",
|
||||
rsrc_data->common_data->secure_mode,
|
||||
rsrc_data->secure_mode);
|
||||
}
|
||||
|
||||
if (!rsrc_data->common_data->num_sec_out)
|
||||
rsrc_data->common_data->secure_mode =
|
||||
CAM_SECURE_MODE_NON_SECURE;
|
||||
}
|
||||
mutex_unlock(&rsrc_data->common_data->bus_mutex);
|
||||
|
||||
if (vfe_bus_rd->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
|
||||
vfe_bus_rd->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
||||
|
||||
@@ -597,31 +661,56 @@ static int cam_vfe_bus_release_vfe_bus_rd(void *bus_priv, void *release_args,
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_start_vfe_bus_rd(
|
||||
struct cam_isp_resource_node *vfe_out)
|
||||
struct cam_isp_resource_node *vfe_bus_rd)
|
||||
{
|
||||
int rc = 0, i;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rsrc_data = NULL;
|
||||
struct cam_vfe_bus_rd_ver1_common_data *common_data = NULL;
|
||||
uint32_t irq_reg_mask[1] = {0x6}, val = 0;
|
||||
|
||||
if (!vfe_out) {
|
||||
if (!vfe_bus_rd) {
|
||||
CAM_ERR(CAM_ISP, "Invalid input");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rsrc_data = vfe_out->res_priv;
|
||||
rsrc_data = vfe_bus_rd->res_priv;
|
||||
common_data = rsrc_data->common_data;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Start resource type: %x", rsrc_data->bus_rd_type);
|
||||
CAM_DBG(CAM_ISP, "VFE:%d start RD type:0x%x", vfe_bus_rd->res_id);
|
||||
|
||||
if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
|
||||
if (vfe_bus_rd->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
|
||||
CAM_ERR(CAM_ISP, "Invalid resource state:%d",
|
||||
vfe_out->res_state);
|
||||
vfe_bus_rd->res_state);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (!rsrc_data->is_offline) {
|
||||
val = (common_data->fs_sync_enable << 5) |
|
||||
(common_data->go_cmd_sel << 4);
|
||||
cam_io_w_mb(val, common_data->mem_base +
|
||||
common_data->common_reg->input_if_cmd);
|
||||
}
|
||||
|
||||
for (i = 0; i < rsrc_data->num_rm; i++)
|
||||
rc = cam_vfe_bus_start_rm(rsrc_data->rm_res[i]);
|
||||
vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
|
||||
rsrc_data->irq_handle = cam_irq_controller_subscribe_irq(
|
||||
common_data->bus_irq_controller,
|
||||
CAM_IRQ_PRIORITY_1,
|
||||
irq_reg_mask,
|
||||
vfe_bus_rd,
|
||||
cam_vfe_bus_rd_handle_irq_top_half,
|
||||
cam_vfe_bus_rd_handle_irq_bottom_half,
|
||||
vfe_bus_rd->tasklet_info,
|
||||
&tasklet_bh_api);
|
||||
|
||||
if (rsrc_data->irq_handle < 1) {
|
||||
CAM_ERR(CAM_ISP, "Failed to subscribe BUS RD IRQ");
|
||||
rsrc_data->irq_handle = 0;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
vfe_bus_rd->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -631,7 +720,6 @@ static int cam_vfe_bus_stop_vfe_bus_rd(
|
||||
int rc = 0, i;
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rsrc_data = NULL;
|
||||
|
||||
CAM_DBG(CAM_ISP, "E:Stop rd Res");
|
||||
if (!vfe_bus_rd) {
|
||||
CAM_ERR(CAM_ISP, "Invalid input");
|
||||
return -EINVAL;
|
||||
@@ -641,14 +729,26 @@ static int cam_vfe_bus_stop_vfe_bus_rd(
|
||||
|
||||
if (vfe_bus_rd->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
|
||||
vfe_bus_rd->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
|
||||
CAM_DBG(CAM_ISP, "vfe_out res_state is %d",
|
||||
CAM_DBG(CAM_ISP, "VFE:%d Bus RD 0x%x state: %d",
|
||||
rsrc_data->common_data->core_index, vfe_bus_rd->res_id,
|
||||
vfe_bus_rd->res_state);
|
||||
return rc;
|
||||
}
|
||||
for (i = 0; i < rsrc_data->num_rm; i++)
|
||||
rc = cam_vfe_bus_stop_rm(rsrc_data->rm_res[i]);
|
||||
|
||||
if (rsrc_data->irq_handle) {
|
||||
rc = cam_irq_controller_unsubscribe_irq(
|
||||
rsrc_data->common_data->bus_irq_controller,
|
||||
rsrc_data->irq_handle);
|
||||
rsrc_data->irq_handle = 0;
|
||||
}
|
||||
|
||||
vfe_bus_rd->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
|
||||
CAM_DBG(CAM_ISP, "VFE:%d stopped Bus RD:0x%x",
|
||||
rsrc_data->common_data->core_index,
|
||||
vfe_bus_rd->res_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -663,7 +763,7 @@ static int cam_vfe_bus_init_vfe_bus_read_resource(uint32_t index,
|
||||
bus_rd_hw_info->vfe_bus_rd_hw_info[index].vfe_bus_rd_type;
|
||||
|
||||
if (vfe_bus_rd_resc_type < 0 ||
|
||||
vfe_bus_rd_resc_type > CAM_VFE_BUS_RD_VER1_VFE_BUSRD_RDI0) {
|
||||
vfe_bus_rd_resc_type >= CAM_VFE_BUS_RD_VER1_VFE_BUSRD_MAX) {
|
||||
CAM_ERR(CAM_ISP, "Init VFE Out failed, Invalid type=%d",
|
||||
vfe_bus_rd_resc_type);
|
||||
return -EINVAL;
|
||||
@@ -701,7 +801,7 @@ static int cam_vfe_bus_init_vfe_bus_read_resource(uint32_t index,
|
||||
|
||||
vfe_bus_rd->start = cam_vfe_bus_start_vfe_bus_rd;
|
||||
vfe_bus_rd->stop = cam_vfe_bus_stop_vfe_bus_rd;
|
||||
vfe_bus_rd->process_cmd = cam_vfe_bus_process_cmd;
|
||||
vfe_bus_rd->process_cmd = cam_vfe_bus_rd_process_cmd;
|
||||
vfe_bus_rd->hw_intf = bus_rd_priv->common_data.hw_intf;
|
||||
|
||||
return 0;
|
||||
@@ -743,10 +843,15 @@ static int cam_vfe_bus_rd_ver1_handle_irq(uint32_t evt_id,
|
||||
struct cam_irq_th_payload *th_payload)
|
||||
{
|
||||
struct cam_vfe_bus_rd_ver1_priv *bus_priv;
|
||||
int rc = 0;
|
||||
|
||||
bus_priv = th_payload->handler_priv;
|
||||
CAM_DBG(CAM_ISP, "BUS READ IRQ Received");
|
||||
return 0;
|
||||
CAM_DBG(CAM_ISP, "Top Bus RD IRQ Received");
|
||||
|
||||
rc = cam_irq_controller_handle_irq(evt_id,
|
||||
bus_priv->common_data.bus_irq_controller);
|
||||
|
||||
return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
@@ -759,7 +864,6 @@ static int cam_vfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
struct cam_vfe_bus_rd_ver1_rm_resource_data *rm_data = NULL;
|
||||
uint32_t *reg_val_pair;
|
||||
uint32_t i, j, size = 0;
|
||||
uint32_t val;
|
||||
uint32_t buf_size = 0;
|
||||
|
||||
bus_priv = (struct cam_vfe_bus_rd_ver1_priv *) priv;
|
||||
@@ -796,39 +900,32 @@ static int cam_vfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
rm_data = vfe_bus_rd_data->rm_res[i]->res_priv;
|
||||
|
||||
/* update size register */
|
||||
rm_data->width = io_cfg->planes[i].width;
|
||||
cam_vfe_bus_rd_pxls_to_bytes(io_cfg->planes[i].width,
|
||||
rm_data->unpacker_cfg, &rm_data->width);
|
||||
rm_data->height = io_cfg->planes[i].height;
|
||||
CAM_DBG(CAM_ISP, "RM %d image w 0x%x h 0x%x image size 0x%x",
|
||||
rm_data->index, rm_data->width, rm_data->height,
|
||||
buf_size);
|
||||
|
||||
buf_size = ((rm_data->width)&(0x0000FFFF)) |
|
||||
((rm_data->height<<16)&(0xFFFF0000));
|
||||
|
||||
CAM_DBG(CAM_ISP, "size offset 0x%x buf_size 0x%x",
|
||||
rm_data->hw_regs->buf_size, buf_size);
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
rm_data->hw_regs->buf_size, buf_size);
|
||||
CAM_DBG(CAM_ISP, "RM %d image size 0x%x",
|
||||
CAM_DBG(CAM_ISP, "VFE:%d RM:%d image_size:0x%X",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, reg_val_pair[j-1]);
|
||||
|
||||
val = rm_data->width;
|
||||
CAM_DBG(CAM_ISP, "io_cfg stride 0x%x", val);
|
||||
rm_data->stride = io_cfg->planes[i].plane_stride;
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
rm_data->hw_regs->stride,
|
||||
val);
|
||||
rm_data->stride = val;
|
||||
CAM_DBG(CAM_ISP, "RM %d image stride 0x%x",
|
||||
rm_data->hw_regs->stride, rm_data->stride);
|
||||
CAM_DBG(CAM_ISP, "VFE:%d RM:%d image_stride:0x%X",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, reg_val_pair[j-1]);
|
||||
|
||||
/* RM Image address */
|
||||
CAM_DBG(CAM_ISP, "image_addr offset %x",
|
||||
rm_data->hw_regs->image_addr);
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
rm_data->hw_regs->image_addr,
|
||||
update_buf->rm_update->image_buf[i] +
|
||||
rm_data->offset);
|
||||
CAM_DBG(CAM_ISP, "RM %d image address 0x%x",
|
||||
CAM_DBG(CAM_ISP, "VFE:%d RM:%d image_address:0x%X",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, reg_val_pair[j-1]);
|
||||
rm_data->img_addr = reg_val_pair[j-1];
|
||||
|
||||
@@ -889,43 +986,93 @@ static int cam_vfe_bus_rd_update_fs_cfg(void *priv, void *cmd_args,
|
||||
common_data = rm_data->common_data;
|
||||
|
||||
rm_data->format = fe_cfg->format;
|
||||
CAM_DBG(CAM_ISP, "format: 0x%x", rm_data->format);
|
||||
|
||||
rm_data->unpacker_cfg = fe_cfg->unpacker_cfg;
|
||||
CAM_DBG(CAM_ISP, "unpacker_cfg: 0x%x", rm_data->unpacker_cfg);
|
||||
|
||||
rm_data->latency_buf_allocation = fe_cfg->latency_buf_size;
|
||||
CAM_DBG(CAM_ISP, "latency_buf_allocation: 0x%x",
|
||||
rm_data->latency_buf_allocation);
|
||||
|
||||
rm_data->stride = fe_cfg->stride;
|
||||
CAM_DBG(CAM_ISP, "stride: 0x%x", rm_data->stride);
|
||||
|
||||
rm_data->go_cmd_sel = fe_cfg->go_cmd_sel;
|
||||
CAM_DBG(CAM_ISP, "go_cmd_sel: 0x%x", rm_data->go_cmd_sel);
|
||||
|
||||
rm_data->fs_sync_enable = fe_cfg->fs_sync_enable;
|
||||
CAM_DBG(CAM_ISP, "fs_sync_enable: 0x%x",
|
||||
rm_data->fs_sync_enable);
|
||||
|
||||
rm_data->hbi_count = fe_cfg->hbi_count;
|
||||
CAM_DBG(CAM_ISP, "hbi_count: 0x%x", rm_data->hbi_count);
|
||||
|
||||
rm_data->fs_line_sync_en = fe_cfg->fs_line_sync_en;
|
||||
CAM_DBG(CAM_ISP, "fs_line_sync_en: 0x%x",
|
||||
rm_data->fs_line_sync_en);
|
||||
|
||||
rm_data->fs_mode = fe_cfg->fs_mode;
|
||||
CAM_DBG(CAM_ISP, "fs_mode: 0x%x", rm_data->fs_mode);
|
||||
|
||||
rm_data->min_vbi = fe_cfg->min_vbi;
|
||||
CAM_DBG(CAM_ISP, "min_vbi: 0x%x", rm_data->min_vbi);
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"VFE:%d RM:%d format:0x%x unpacker_cfg:0x%x",
|
||||
rm_data->format, rm_data->unpacker_cfg);
|
||||
CAM_DBG(CAM_ISP,
|
||||
"latency_buf_alloc:0x%x stride:0x%x go_cmd_sel:0x%x",
|
||||
rm_data->latency_buf_allocation, rm_data->stride,
|
||||
rm_data->go_cmd_sel);
|
||||
CAM_DBG(CAM_ISP,
|
||||
"fs_sync_en:%d hbi_cnt:0x%x fs_mode:0x%x min_vbi:0x%x",
|
||||
rm_data->fs_sync_enable, rm_data->hbi_count,
|
||||
rm_data->fs_mode, rm_data->min_vbi);
|
||||
}
|
||||
bus_priv->common_data.fs_sync_enable = fe_cfg->fs_sync_enable;
|
||||
bus_priv->common_data.go_cmd_sel = fe_cfg->go_cmd_sel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_rd_add_go_cmd(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *rd_data;
|
||||
struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
|
||||
uint32_t reg_val_pair[2 * CAM_VFE_BUS_RD_VER1_VFE_BUSRD_MAX];
|
||||
struct cam_vfe_bus_rd_ver1_rm_resource_data *rsrc_data;
|
||||
int i = 0;
|
||||
uint32_t val = 0, size = 0, offset = 0;
|
||||
|
||||
if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
|
||||
CAM_ERR(CAM_ISP, "invalid ars size");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cdm_args || !cdm_args->res) {
|
||||
CAM_ERR(CAM_ISP, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rd_data = (struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *) priv;
|
||||
|
||||
cdm_util_ops = (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
|
||||
|
||||
if (!cdm_util_ops) {
|
||||
CAM_ERR(CAM_ISP, "Invalid CDM ops");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rd_data->num_rm; i++) {
|
||||
size = cdm_util_ops->cdm_required_size_reg_random(1);
|
||||
/* since cdm returns dwords, we need to convert it into bytes */
|
||||
if ((size * 4) > cdm_args->cmd.size) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"buf size:%d is not sufficient, expected: %d",
|
||||
cdm_args->cmd.size, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rsrc_data = rd_data->rm_res[i]->res_priv;
|
||||
offset = rsrc_data->common_data->common_reg->input_if_cmd;
|
||||
val = cam_io_r_mb(rsrc_data->common_data->mem_base + offset);
|
||||
val |= 0x1;
|
||||
reg_val_pair[i * 2] = offset;
|
||||
reg_val_pair[i * 2 + 1] = val;
|
||||
CAM_DBG(CAM_ISP, "VFE:%d Bus RD go_cmd: 0x%x offset 0x%x",
|
||||
rd_data->common_data->core_index,
|
||||
reg_val_pair[i * 2 + 1], reg_val_pair[i * 2]);
|
||||
}
|
||||
|
||||
cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr,
|
||||
1, reg_val_pair);
|
||||
|
||||
cdm_args->cmd.used_bytes = size * 4;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_start_hw(void *hw_priv,
|
||||
void *start_hw_args, uint32_t arg_size)
|
||||
{
|
||||
@@ -943,7 +1090,7 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
|
||||
{
|
||||
struct cam_vfe_bus_rd_ver1_priv *bus_priv = hw_priv;
|
||||
uint32_t top_irq_reg_mask[3] = {0};
|
||||
uint32_t offset = 0, val = 0;
|
||||
uint32_t offset = 0;
|
||||
struct cam_vfe_bus_rd_ver1_reg_offset_common *common_reg;
|
||||
|
||||
if (!bus_priv) {
|
||||
@@ -951,7 +1098,7 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
common_reg = bus_priv->common_data.common_reg;
|
||||
top_irq_reg_mask[0] = (1 << 23);
|
||||
top_irq_reg_mask[0] = (1 << bus_priv->top_irq_shift);
|
||||
|
||||
bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
|
||||
bus_priv->common_data.vfe_irq_controller,
|
||||
@@ -968,23 +1115,15 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
|
||||
bus_priv->irq_handle = 0;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* no clock gating at bus input */
|
||||
offset = common_reg->cgc_ovd;
|
||||
cam_io_w_mb(0x0, bus_priv->common_data.mem_base + offset);
|
||||
cam_io_w_mb(0x1, bus_priv->common_data.mem_base + offset);
|
||||
|
||||
/* BUS_RD_TEST_BUS_CTRL */
|
||||
offset = common_reg->test_bus_ctrl;
|
||||
cam_io_w_mb(0x0, bus_priv->common_data.mem_base + offset);
|
||||
|
||||
/* Read irq mask */
|
||||
offset = common_reg->irq_reg_info.irq_reg_set->mask_reg_offset;
|
||||
cam_io_w_mb(0x5, bus_priv->common_data.mem_base + offset);
|
||||
|
||||
/* INPUT_IF_CMD */
|
||||
val = (bus_priv->common_data.fs_sync_enable << 5) |
|
||||
(bus_priv->common_data.go_cmd_sel << 4);
|
||||
offset = common_reg->input_if_cmd;
|
||||
cam_io_w_mb(val, bus_priv->common_data.mem_base + offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -999,13 +1138,6 @@ static int cam_vfe_bus_deinit_hw(void *hw_priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bus_priv->error_irq_handle) {
|
||||
rc = cam_irq_controller_unsubscribe_irq(
|
||||
bus_priv->common_data.bus_irq_controller,
|
||||
bus_priv->error_irq_handle);
|
||||
bus_priv->error_irq_handle = 0;
|
||||
}
|
||||
|
||||
if (bus_priv->irq_handle) {
|
||||
rc = cam_irq_controller_unsubscribe_irq(
|
||||
bus_priv->common_data.vfe_irq_controller,
|
||||
@@ -1016,13 +1148,13 @@ static int cam_vfe_bus_deinit_hw(void *hw_priv,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_vfe_bus_process_cmd(void *priv,
|
||||
static int __cam_vfe_bus_rd_process_cmd(void *priv,
|
||||
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
return cam_vfe_bus_process_cmd(priv, cmd_type, cmd_args, arg_size);
|
||||
return cam_vfe_bus_rd_process_cmd(priv, cmd_type, cmd_args, arg_size);
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_process_cmd(
|
||||
static int cam_vfe_bus_rd_process_cmd(
|
||||
struct cam_isp_resource_node *priv,
|
||||
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
@@ -1046,6 +1178,9 @@ static int cam_vfe_bus_process_cmd(
|
||||
case CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD:
|
||||
rc = cam_vfe_bus_rd_update_fs_cfg(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_FE_TRIGGER_CMD:
|
||||
rc = cam_vfe_bus_rd_add_go_cmd(priv, cmd_args, arg_size);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
|
||||
cmd_type);
|
||||
@@ -1104,6 +1239,7 @@ int cam_vfe_bus_rd_ver1_init(
|
||||
bus_priv->common_data.hw_intf = hw_intf;
|
||||
bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
|
||||
bus_priv->common_data.common_reg = &bus_rd_hw_info->common_reg;
|
||||
bus_priv->top_irq_shift = bus_rd_hw_info->top_irq_shift;
|
||||
|
||||
mutex_init(&bus_priv->common_data.bus_mutex);
|
||||
|
||||
@@ -1143,7 +1279,7 @@ int cam_vfe_bus_rd_ver1_init(
|
||||
vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
|
||||
vfe_bus_local->top_half_handler = cam_vfe_bus_rd_ver1_handle_irq;
|
||||
vfe_bus_local->bottom_half_handler = NULL;
|
||||
vfe_bus_local->hw_ops.process_cmd = __cam_vfe_bus_process_cmd;
|
||||
vfe_bus_local->hw_ops.process_cmd = __cam_vfe_bus_rd_process_cmd;
|
||||
|
||||
*vfe_bus = vfe_bus_local;
|
||||
|
||||
|
@@ -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(
|
||||
@@ -255,12 +257,13 @@ int cam_vfe_camif_ver3_acquire_resource(
|
||||
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->horizontal_bin =
|
||||
acquire_data->vfe_in.in_port->horizontal_bin;
|
||||
camif_data->qcfa_bin = acquire_data->vfe_in.in_port->qcfa_bin;
|
||||
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->is_dual = acquire_data->vfe_in.is_dual;
|
||||
camif_data->qcfa_bin = acquire_data->vfe_in.in_port->qcfa_bin;
|
||||
camif_data->horizontal_bin =
|
||||
acquire_data->vfe_in.in_port->horizontal_bin;
|
||||
|
||||
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 */
|
||||
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);
|
||||
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);
|
||||
|
Reference in New Issue
Block a user