msm: camera: isp: Config hardware in work queue
Currently requests for offline IFE are applied from tasklet context or from an ioctl thread within a critical section protected by a spinlock. In both of these cases, preemtion is disabled but CDM requires mutex locks during this operation. Therefore a work queue is added in this change to handle apply request for offline IFE. CRs-Fixed: 2606911 Change-Id: Ie893a626bc274d026fb878f1f19830e990be6dc6 Signed-off-by: Venkat Chinta <vchinta@codeaurora.org>
This commit is contained in:
@@ -1047,14 +1047,22 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int __cam_isp_ctx_apply_req_offline(
|
static int __cam_isp_ctx_apply_req_offline(
|
||||||
struct cam_context *ctx, uint32_t next_state,
|
void *priv, void *data)
|
||||||
struct cam_isp_context *ctx_isp)
|
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
struct cam_context *ctx = NULL;
|
||||||
|
struct cam_isp_context *ctx_isp = priv;
|
||||||
struct cam_ctx_request *req;
|
struct cam_ctx_request *req;
|
||||||
struct cam_isp_ctx_req *req_isp;
|
struct cam_isp_ctx_req *req_isp;
|
||||||
struct cam_hw_config_args cfg;
|
struct cam_hw_config_args cfg;
|
||||||
|
|
||||||
|
if (!ctx_isp) {
|
||||||
|
CAM_ERR(CAM_ISP, "Invalid ctx_isp:%pK", ctx);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ctx = ctx_isp->base;
|
||||||
|
|
||||||
if (list_empty(&ctx->pending_req_list)) {
|
if (list_empty(&ctx->pending_req_list)) {
|
||||||
CAM_DBG(CAM_ISP, "No pending requests to apply");
|
CAM_DBG(CAM_ISP, "No pending requests to apply");
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
@@ -1067,8 +1075,10 @@ static int __cam_isp_ctx_apply_req_offline(
|
|||||||
if (ctx_isp->active_req_cnt >= 2)
|
if (ctx_isp->active_req_cnt >= 2)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
spin_lock_bh(&ctx->lock);
|
||||||
req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
|
req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
|
||||||
list);
|
list);
|
||||||
|
spin_unlock_bh(&ctx->lock);
|
||||||
|
|
||||||
CAM_DBG(CAM_REQ, "Apply request %lld in substate %d ctx %u",
|
CAM_DBG(CAM_REQ, "Apply request %lld in substate %d ctx %u",
|
||||||
req->request_id, ctx_isp->substate_activated, ctx->ctx_id);
|
req->request_id, ctx_isp->substate_activated, ctx->ctx_id);
|
||||||
@@ -1087,13 +1097,21 @@ static int __cam_isp_ctx_apply_req_offline(
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
|
CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
|
||||||
} else {
|
} else {
|
||||||
|
spin_lock_bh(&ctx->lock);
|
||||||
|
|
||||||
atomic_set(&ctx_isp->rxd_epoch, 0);
|
atomic_set(&ctx_isp->rxd_epoch, 0);
|
||||||
ctx_isp->substate_activated = next_state;
|
|
||||||
|
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_APPLIED;
|
||||||
ctx_isp->last_applied_req_id = req->request_id;
|
ctx_isp->last_applied_req_id = req->request_id;
|
||||||
|
|
||||||
list_del_init(&req->list);
|
list_del_init(&req->list);
|
||||||
list_add_tail(&req->list, &ctx->wait_req_list);
|
list_add_tail(&req->list, &ctx->wait_req_list);
|
||||||
|
|
||||||
|
spin_unlock_bh(&ctx->lock);
|
||||||
|
|
||||||
CAM_DBG(CAM_ISP, "New substate state %d, applied req %lld",
|
CAM_DBG(CAM_ISP, "New substate state %d, applied req %lld",
|
||||||
next_state, ctx_isp->last_applied_req_id);
|
CAM_ISP_CTX_ACTIVATED_APPLIED,
|
||||||
|
ctx_isp->last_applied_req_id);
|
||||||
|
|
||||||
__cam_isp_ctx_update_state_monitor_array(ctx_isp,
|
__cam_isp_ctx_update_state_monitor_array(ctx_isp,
|
||||||
CAM_ISP_STATE_CHANGE_TRIGGER_APPLIED,
|
CAM_ISP_STATE_CHANGE_TRIGGER_APPLIED,
|
||||||
@@ -1103,6 +1121,26 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_isp_ctx_schedule_apply_req_offline(
|
||||||
|
struct cam_isp_context *ctx_isp)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct crm_workq_task *task;
|
||||||
|
|
||||||
|
task = cam_req_mgr_workq_get_task(ctx_isp->workq);
|
||||||
|
if (!task) {
|
||||||
|
CAM_ERR(CAM_ISP, "No task for worker");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
task->process_cb = __cam_isp_ctx_apply_req_offline;
|
||||||
|
rc = cam_req_mgr_workq_enqueue_task(task, ctx_isp, CRM_TASK_PRIORITY_0);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_ISP, "Failed to schedule task rc:%d", rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int __cam_isp_ctx_offline_epoch_in_activated_state(
|
static int __cam_isp_ctx_offline_epoch_in_activated_state(
|
||||||
struct cam_isp_context *ctx_isp, void *evt_data)
|
struct cam_isp_context *ctx_isp, void *evt_data)
|
||||||
{
|
{
|
||||||
@@ -1123,8 +1161,7 @@ static int __cam_isp_ctx_offline_epoch_in_activated_state(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__cam_isp_ctx_apply_req_offline(ctx, CAM_ISP_CTX_ACTIVATED_APPLIED,
|
__cam_isp_ctx_schedule_apply_req_offline(ctx_isp);
|
||||||
ctx_isp);
|
|
||||||
|
|
||||||
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
|
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
|
||||||
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
|
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
|
||||||
@@ -3887,10 +3924,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
|
|||||||
req->request_id, ctx->ctx_id);
|
req->request_id, ctx->ctx_id);
|
||||||
|
|
||||||
if (ctx_isp->offline_context && atomic_read(&ctx_isp->rxd_epoch)) {
|
if (ctx_isp->offline_context && atomic_read(&ctx_isp->rxd_epoch)) {
|
||||||
spin_lock_bh(&ctx->lock);
|
__cam_isp_ctx_schedule_apply_req_offline(ctx_isp);
|
||||||
__cam_isp_ctx_apply_req_offline(ctx,
|
|
||||||
CAM_ISP_CTX_ACTIVATED_APPLIED, ctx_isp);
|
|
||||||
spin_unlock_bh(&ctx->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -4336,6 +4370,13 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
|
|||||||
cam_isp_ctx_offline_state_machine_irq;
|
cam_isp_ctx_offline_state_machine_irq;
|
||||||
ctx_isp->substate_machine = NULL;
|
ctx_isp->substate_machine = NULL;
|
||||||
ctx_isp->offline_context = true;
|
ctx_isp->offline_context = true;
|
||||||
|
|
||||||
|
rc = cam_req_mgr_workq_create("offline_ife", 20,
|
||||||
|
&ctx_isp->workq, CRM_WORKQ_USAGE_IRQ, 0);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Failed to create workq for offline IFE rc:%d",
|
||||||
|
rc);
|
||||||
} else {
|
} else {
|
||||||
CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
|
CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
|
||||||
ctx_isp->substate_machine_irq =
|
ctx_isp->substate_machine_irq =
|
||||||
@@ -5252,6 +5293,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
|
|||||||
atomic64_set(&ctx->event_record_head[i], -1);
|
atomic64_set(&ctx->event_record_head[i], -1);
|
||||||
|
|
||||||
cam_isp_context_debug_register();
|
cam_isp_context_debug_register();
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "cam_context.h"
|
#include "cam_context.h"
|
||||||
#include "cam_isp_hw_mgr_intf.h"
|
#include "cam_isp_hw_mgr_intf.h"
|
||||||
|
#include "cam_req_mgr_workq.h"
|
||||||
|
|
||||||
#define CAM_IFE_QTIMER_MUL_FACTOR 10000
|
#define CAM_IFE_QTIMER_MUL_FACTOR 10000
|
||||||
#define CAM_IFE_QTIMER_DIV_FACTOR 192
|
#define CAM_IFE_QTIMER_DIV_FACTOR 192
|
||||||
@@ -257,6 +257,7 @@ struct cam_isp_context_event_record {
|
|||||||
* @isp_device_type: ISP device type
|
* @isp_device_type: ISP device type
|
||||||
* @rxd_epoch: Indicate whether epoch has been received. Used to
|
* @rxd_epoch: Indicate whether epoch has been received. Used to
|
||||||
* decide whether to apply request in offline ctx
|
* decide whether to apply request in offline ctx
|
||||||
|
* @workq: Worker thread for offline ife
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct cam_isp_context {
|
struct cam_isp_context {
|
||||||
@@ -298,6 +299,7 @@ struct cam_isp_context {
|
|||||||
unsigned int init_timestamp;
|
unsigned int init_timestamp;
|
||||||
uint32_t isp_device_type;
|
uint32_t isp_device_type;
|
||||||
atomic_t rxd_epoch;
|
atomic_t rxd_epoch;
|
||||||
|
struct cam_req_mgr_core_workq *workq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -648,6 +648,11 @@ static void cam_ife_hw_mgr_print_acquire_info(
|
|||||||
|
|
||||||
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_csid,
|
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_csid,
|
||||||
struct cam_isp_hw_mgr_res, list);
|
struct cam_isp_hw_mgr_res, list);
|
||||||
|
|
||||||
|
if (hw_mgr_ctx->is_offline)
|
||||||
|
hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
|
||||||
|
struct cam_isp_hw_mgr_res, list);
|
||||||
|
|
||||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||||
hw_res = hw_mgr_res->hw_res[i];
|
hw_res = hw_mgr_res->hw_res[i];
|
||||||
if (hw_res && hw_res->hw_intf)
|
if (hw_res && hw_res->hw_intf)
|
||||||
@@ -2173,7 +2178,7 @@ static int cam_ife_hw_mgr_preprocess_port(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_ife_hw_mgr_acquire_offline_res_ife_bus_rd(
|
static int cam_ife_hw_mgr_acquire_res_ife_bus_rd(
|
||||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||||
struct cam_isp_in_port_generic_info *in_port)
|
struct cam_isp_in_port_generic_info *in_port)
|
||||||
{
|
{
|
||||||
@@ -2385,7 +2390,7 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_ife_mgr_acquire_hw_for_fe_ctx(
|
static int cam_ife_mgr_acquire_hw_for_offline_ctx(
|
||||||
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
struct cam_ife_hw_mgr_ctx *ife_ctx,
|
||||||
struct cam_isp_in_port_generic_info *in_port,
|
struct cam_isp_in_port_generic_info *in_port,
|
||||||
uint32_t *num_pix_port,
|
uint32_t *num_pix_port,
|
||||||
@@ -2417,7 +2422,7 @@ static int cam_ife_mgr_acquire_hw_for_fe_ctx(
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = cam_ife_hw_mgr_acquire_offline_res_ife_bus_rd(ife_ctx, in_port);
|
rc = cam_ife_hw_mgr_acquire_res_ife_bus_rd(ife_ctx, in_port);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_ISP, "Acquire IFE BUS RD resource Failed");
|
CAM_ERR(CAM_ISP, "Acquire IFE BUS RD resource Failed");
|
||||||
@@ -2486,17 +2491,21 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
|
|||||||
cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port, &ipp_count,
|
cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port, &ipp_count,
|
||||||
&rdi_count, &ppp_count, &ife_rd_count, &lcr_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) {
|
if (!ipp_count && !rdi_count && !ppp_count && !lcr_count) {
|
||||||
CAM_ERR(CAM_ISP,
|
CAM_ERR(CAM_ISP,
|
||||||
"No PIX or RDI or PPP or LCR resource");
|
"No PIX or RDI or PPP or LCR resource");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ife_rd_count) {
|
||||||
|
rc = cam_ife_hw_mgr_acquire_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 || lcr_count) {
|
if (ipp_count || lcr_count) {
|
||||||
/* get ife csid IPP resource */
|
/* get ife csid IPP resource */
|
||||||
rc = cam_ife_hw_mgr_acquire_res_ife_csid_pxl(ife_ctx,
|
rc = cam_ife_hw_mgr_acquire_res_ife_csid_pxl(ife_ctx,
|
||||||
@@ -2937,8 +2946,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
|||||||
goto free_mem;
|
goto free_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ife_ctx->is_fe_enabled)
|
if (ife_ctx->is_offline)
|
||||||
rc = cam_ife_mgr_acquire_hw_for_fe_ctx(
|
rc = cam_ife_mgr_acquire_hw_for_offline_ctx(
|
||||||
ife_ctx, in_port,
|
ife_ctx, in_port,
|
||||||
&num_pix_port_per_in,
|
&num_pix_port_per_in,
|
||||||
&acquire_args->acquired_hw_id[i],
|
&acquire_args->acquired_hw_id[i],
|
||||||
|
Reference in New Issue
Block a user