From fc8ddd752d08cd9b95d512e361a977f46a2e3f0c Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 30 Oct 2019 18:30:06 +0530 Subject: [PATCH] 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 --- drivers/cam_isp/cam_isp_context.c | 9 ++++ drivers/cam_req_mgr/cam_req_mgr_core.c | 55 +++++++++++++++++++++ drivers/cam_req_mgr/cam_req_mgr_interface.h | 16 ++++++ drivers/cam_req_mgr/cam_req_mgr_timer.h | 12 +++-- 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index b251d75ac2..1a66070585 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -2165,6 +2165,7 @@ static int __cam_isp_ctx_flush_req_in_top_state( struct cam_hw_stop_args stop_args; struct cam_hw_reset_args reset_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; @@ -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_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); if (!list_empty(&ctx->wait_req_list)) rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list, diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index faa15479ec..00677b9d86 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -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; + + if (link->watchdog->pause_timer) + return; + task = cam_req_mgr_workq_get_task(link->workq); if (!task) { CAM_ERR(CAM_CRM, "No empty task"); @@ -2643,6 +2647,52 @@ end: 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() * @@ -2682,6 +2732,10 @@ static int cam_req_mgr_cb_notify_trigger( rc = -EPERM; goto end; } + + if (link->watchdog->pause_timer) + link->watchdog->pause_timer = false; + crm_timer_reset(link->watchdog); 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_err = cam_req_mgr_cb_notify_err, .add_req = cam_req_mgr_cb_add_req, + .notify_timer = cam_req_mgr_cb_notify_timer, }; /** diff --git a/drivers/cam_req_mgr/cam_req_mgr_interface.h b/drivers/cam_req_mgr/cam_req_mgr_interface.h index f4b662dd41..5df13b26e2 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/cam_req_mgr/cam_req_mgr_interface.h @@ -14,6 +14,7 @@ struct cam_req_mgr_trigger_notify; struct cam_req_mgr_error_notify; struct cam_req_mgr_add_request; +struct cam_req_mgr_timer_notify; struct cam_req_mgr_device_info; struct cam_req_mgr_core_dev_link_setup; struct cam_req_mgr_apply_request; @@ -35,6 +36,7 @@ typedef int (*cam_req_mgr_notify_trigger)( struct cam_req_mgr_trigger_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_notify_timer)(struct cam_req_mgr_timer_notify *); /** * @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_err notify_err; 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; }; +/** + * 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 * @link_hdl : link identifier diff --git a/drivers/cam_req_mgr/cam_req_mgr_timer.h b/drivers/cam_req_mgr/cam_req_mgr_timer.h index 9f9ba71a38..be200f1b26 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_timer.h +++ b/drivers/cam_req_mgr/cam_req_mgr_timer.h @@ -1,6 +1,6 @@ /* 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_ @@ -12,16 +12,18 @@ #include "cam_req_mgr_core_defs.h" /** struct cam_req_mgr_timer - * @expires : timeout value for timer - * @sys_timer : system timer variable - * @parent : priv data - link pointer - * @timer_cb : callback func which will be called when timeout expires + * @expires : timeout value for timer + * @sys_timer : system timer variable + * @parent : priv data - link pointer + * @timer_cb : callback func which will be called when timeout expires + * @pause_timer : flag to pause SOF timer */ struct cam_req_mgr_timer { int32_t expires; struct timer_list sys_timer; void *parent; void (*timer_cb)(struct timer_list *timer_data); + bool pause_timer; }; /**