msm: camera: isp: Notify CRM to pause SOF timer after flush

Adding CRM interface to stop SOF timer from isp during flush.
During flush hardware is getting stop and will not send SOF
notification to CRM so need to pause SOF timer. Whenever SOF
timer will get expire,do not need to send error to UMD during
pause time.

CRs-Fixed: 2564389
Change-Id: I6d85f2c658c30dbe211f0ec9d83bca323a5c265b
Signed-off-by: Chandan Kumar Jha <cjha@codeaurora.org>
This commit is contained in:
Chandan Kumar Jha
2019-10-30 18:30:06 +05:30
committed by Gerrit - the friendly Code Review server
parent f123cac5fc
commit fc8ddd752d
4 changed files with 87 additions and 5 deletions

View File

@@ -2165,6 +2165,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
struct cam_hw_stop_args stop_args; struct cam_hw_stop_args stop_args;
struct cam_hw_reset_args reset_args; struct cam_hw_reset_args reset_args;
struct cam_hw_cmd_args hw_cmd_args; struct cam_hw_cmd_args hw_cmd_args;
struct cam_req_mgr_timer_notify timer;
ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
@@ -2210,6 +2211,14 @@ static int __cam_isp_ctx_flush_req_in_top_state(
CAM_INFO(CAM_ISP, "Stop HW complete. Reset HW next."); CAM_INFO(CAM_ISP, "Stop HW complete. Reset HW next.");
CAM_DBG(CAM_ISP, "Flush wait and active lists"); CAM_DBG(CAM_ISP, "Flush wait and active lists");
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_timer) {
timer.link_hdl = ctx->link_hdl;
timer.dev_hdl = ctx->dev_hdl;
timer.state = false;
ctx->ctx_crm_intf->notify_timer(&timer);
}
spin_lock_bh(&ctx->lock); spin_lock_bh(&ctx->lock);
if (!list_empty(&ctx->wait_req_list)) if (!list_empty(&ctx->wait_req_list))
rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list, rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,

View File

@@ -1744,6 +1744,10 @@ static void __cam_req_mgr_sof_freeze(struct timer_list *timer_data)
} }
link = (struct cam_req_mgr_core_link *)timer->parent; link = (struct cam_req_mgr_core_link *)timer->parent;
if (link->watchdog->pause_timer)
return;
task = cam_req_mgr_workq_get_task(link->workq); task = cam_req_mgr_workq_get_task(link->workq);
if (!task) { if (!task) {
CAM_ERR(CAM_CRM, "No empty task"); CAM_ERR(CAM_CRM, "No empty task");
@@ -2643,6 +2647,52 @@ end:
return rc; return rc;
} }
/**
* cam_req_mgr_cb_notify_timer()
*
* @brief : Notify SOF timer to pause after flush
* @timer_data : contains information about frame_id, link etc.
*
* @return : 0 on success
*
*/
static int cam_req_mgr_cb_notify_timer(
struct cam_req_mgr_timer_notify *timer_data)
{
int rc = 0;
struct cam_req_mgr_core_link *link = NULL;
if (!timer_data) {
CAM_ERR(CAM_CRM, "timer data is NULL");
rc = -EINVAL;
goto end;
}
link = (struct cam_req_mgr_core_link *)
cam_get_device_priv(timer_data->link_hdl);
if (!link) {
CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl);
rc = -EINVAL;
goto end;
}
spin_lock_bh(&link->link_state_spin_lock);
if (link->state < CAM_CRM_LINK_STATE_READY) {
CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
spin_unlock_bh(&link->link_state_spin_lock);
rc = -EPERM;
goto end;
}
spin_unlock_bh(&link->link_state_spin_lock);
if (!timer_data->state)
link->watchdog->pause_timer = true;
end:
return rc;
}
/** /**
* cam_req_mgr_cb_notify_trigger() * cam_req_mgr_cb_notify_trigger()
* *
@@ -2682,6 +2732,10 @@ static int cam_req_mgr_cb_notify_trigger(
rc = -EPERM; rc = -EPERM;
goto end; goto end;
} }
if (link->watchdog->pause_timer)
link->watchdog->pause_timer = false;
crm_timer_reset(link->watchdog); crm_timer_reset(link->watchdog);
spin_unlock_bh(&link->link_state_spin_lock); spin_unlock_bh(&link->link_state_spin_lock);
@@ -2711,6 +2765,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = {
.notify_trigger = cam_req_mgr_cb_notify_trigger, .notify_trigger = cam_req_mgr_cb_notify_trigger,
.notify_err = cam_req_mgr_cb_notify_err, .notify_err = cam_req_mgr_cb_notify_err,
.add_req = cam_req_mgr_cb_add_req, .add_req = cam_req_mgr_cb_add_req,
.notify_timer = cam_req_mgr_cb_notify_timer,
}; };
/** /**

View File

@@ -14,6 +14,7 @@
struct cam_req_mgr_trigger_notify; struct cam_req_mgr_trigger_notify;
struct cam_req_mgr_error_notify; struct cam_req_mgr_error_notify;
struct cam_req_mgr_add_request; struct cam_req_mgr_add_request;
struct cam_req_mgr_timer_notify;
struct cam_req_mgr_device_info; struct cam_req_mgr_device_info;
struct cam_req_mgr_core_dev_link_setup; struct cam_req_mgr_core_dev_link_setup;
struct cam_req_mgr_apply_request; struct cam_req_mgr_apply_request;
@@ -35,6 +36,7 @@ typedef int (*cam_req_mgr_notify_trigger)(
struct cam_req_mgr_trigger_notify *); struct cam_req_mgr_trigger_notify *);
typedef int (*cam_req_mgr_notify_err)(struct cam_req_mgr_error_notify *); typedef int (*cam_req_mgr_notify_err)(struct cam_req_mgr_error_notify *);
typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *); typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *);
typedef int (*cam_req_mgr_notify_timer)(struct cam_req_mgr_timer_notify *);
/** /**
* @brief: cam req mgr to camera device drivers * @brief: cam req mgr to camera device drivers
@@ -64,6 +66,7 @@ struct cam_req_mgr_crm_cb {
cam_req_mgr_notify_trigger notify_trigger; cam_req_mgr_notify_trigger notify_trigger;
cam_req_mgr_notify_err notify_err; cam_req_mgr_notify_err notify_err;
cam_req_mgr_add_req add_req; cam_req_mgr_add_req add_req;
cam_req_mgr_notify_timer notify_timer;
}; };
/** /**
@@ -206,6 +209,19 @@ struct cam_req_mgr_trigger_notify {
uint64_t sof_timestamp_val; uint64_t sof_timestamp_val;
}; };
/**
* struct cam_req_mgr_timer_notify
* @link_hdl : link identifier
* @dev_hdl : device handle which has sent this req id
* @frame_id : frame id for internal tracking
* @state : timer state i.e ON or OFF
*/
struct cam_req_mgr_timer_notify {
int32_t link_hdl;
int32_t dev_hdl;
bool state;
};
/** /**
* struct cam_req_mgr_error_notify * struct cam_req_mgr_error_notify
* @link_hdl : link identifier * @link_hdl : link identifier

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/ */
#ifndef _CAM_REQ_MGR_TIMER_H_ #ifndef _CAM_REQ_MGR_TIMER_H_
@@ -12,16 +12,18 @@
#include "cam_req_mgr_core_defs.h" #include "cam_req_mgr_core_defs.h"
/** struct cam_req_mgr_timer /** struct cam_req_mgr_timer
* @expires : timeout value for timer * @expires : timeout value for timer
* @sys_timer : system timer variable * @sys_timer : system timer variable
* @parent : priv data - link pointer * @parent : priv data - link pointer
* @timer_cb : callback func which will be called when timeout expires * @timer_cb : callback func which will be called when timeout expires
* @pause_timer : flag to pause SOF timer
*/ */
struct cam_req_mgr_timer { struct cam_req_mgr_timer {
int32_t expires; int32_t expires;
struct timer_list sys_timer; struct timer_list sys_timer;
void *parent; void *parent;
void (*timer_cb)(struct timer_list *timer_data); void (*timer_cb)(struct timer_list *timer_data);
bool pause_timer;
}; };
/** /**