From bdad5088edc20a003a17af0a48654b01bf917298 Mon Sep 17 00:00:00 2001 From: Gaurav Jindal Date: Sat, 23 Jan 2021 17:06:16 +0530 Subject: [PATCH] msm: camera: isp: Change halt reset sequence for dual ife Reset Done irq for slave CSID is not received. Change the programming sequence for dual ife halt reset. Change-Id: If1d559c434e76ff9a9a6b1d1bc4c63f2e472a8aa CRs-Fixed: 2830502 Signed-off-by: Gaurav Jindal --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 7 +- .../isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c | 83 ++++++++++--------- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 0c8fde92e7..04f1d329ca 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -6205,6 +6205,11 @@ static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) return -EPERM; } + if (hw_mgr->csid_global_reset_en) { + CAM_DBG(CAM_ISP, "Path reset not supported"); + return 0; + } + CAM_DBG(CAM_ISP, "Reset CSID and VFE"); rc = cam_ife_hw_mgr_reset_csid(ctx, CAM_IFE_CSID_RESET_PATH); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c index 867044937f..18c4b19724 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include @@ -1151,7 +1151,8 @@ static int cam_ife_csid_ver2_internal_reset( return -EINVAL; } - if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_SLAVE) + if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_SLAVE && + rst_cmd == CAM_IFE_CSID_RESET_CMD_HW_RST) goto wait_only; /*Program the reset location */ @@ -1173,6 +1174,7 @@ static int cam_ife_csid_ver2_internal_reset( cam_io_w_mb(val, mem_base + csid_reg->cmn_reg->reset_cfg_addr); val = 0; + /*Program the cmd */ if (rst_cmd == CAM_IFE_CSID_RESET_CMD_IRQ_CTRL) val = csid_reg->cmn_reg->rst_cmd_irq_ctrl_only_val; @@ -1185,17 +1187,13 @@ static int cam_ife_csid_ver2_internal_reset( val, mem_base + csid_reg->cmn_reg->reset_cmd_addr); wait_only: - /* Mask all top irq except reset */ - cam_io_w_mb( - BIT(csid_reg->cmn_reg->top_reset_irq_shift_val), - mem_base + csid_reg->cmn_reg->top_irq_mask_addr); rc = cam_ife_csid_ver2_wait_for_reset(csid_hw); if (rc) CAM_ERR(CAM_ISP, - "CSID[%d] Reset failed mode %d cmd %d loc %d", + "CSID[%u] Reset failed mode %d cmd %d loc %d", csid_hw->hw_intf->hw_idx, - rst_mode, rst_location, rst_cmd); + rst_mode, rst_cmd, rst_location); return rc; } @@ -1205,7 +1203,6 @@ int cam_ife_csid_ver2_reset(void *hw_priv, struct cam_hw_info *hw_info; struct cam_ife_csid_ver2_hw *csid_hw; struct cam_csid_reset_cfg_args *reset; - uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; int rc = 0; hw_info = (struct cam_hw_info *)hw_priv; @@ -1214,24 +1211,6 @@ int cam_ife_csid_ver2_reset(void *hw_priv, mutex_lock(&csid_hw->hw_info->hw_mutex); - irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = IFE_CSID_VER2_TOP_IRQ_STATUS_RST; - - csid_hw->reset_irq_handle = cam_irq_controller_subscribe_irq( - csid_hw->csid_irq_controller, - CAM_IRQ_PRIORITY_0, - irq_mask, - csid_hw, - cam_ife_csid_ver2_reset_irq_top_half, - NULL, - NULL, - NULL); - - if (csid_hw->reset_irq_handle < 1) { - CAM_ERR(CAM_ISP, "csid[%d] reset irq subscribe fail", - csid_hw->hw_intf->hw_idx); - goto end; - } - switch (reset->reset_type) { case CAM_IFE_CSID_RESET_GLOBAL: rc = cam_ife_csid_ver2_internal_reset(csid_hw, @@ -1239,12 +1218,14 @@ int cam_ife_csid_ver2_reset(void *hw_priv, CAM_IFE_CSID_RESET_LOC_COMPLETE, CAM_CSID_HALT_IMMEDIATELY); break; + case CAM_IFE_CSID_RESET_PATH: rc = cam_ife_csid_ver2_internal_reset(csid_hw, CAM_IFE_CSID_RESET_CMD_HW_RST, CAM_IFE_CSID_RESET_LOC_PATH_ONLY, - CAM_CSID_HALT_AT_FRAME_BOUNDARY); + CAM_CSID_HALT_IMMEDIATELY); break; + default: CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d", reset->reset_type); @@ -1261,13 +1242,6 @@ int cam_ife_csid_ver2_reset(void *hw_priv, csid_hw->hw_intf->hw_idx, reset->reset_type); - if (csid_hw->reset_irq_handle) { - rc = cam_irq_controller_unsubscribe_irq( - csid_hw->csid_irq_controller, - csid_hw->reset_irq_handle); - csid_hw->reset_irq_handle = 0; - } -end: mutex_unlock(&csid_hw->hw_info->hw_mutex); return rc; } @@ -2815,6 +2789,7 @@ static int cam_ife_csid_ver2_enable_core(struct cam_ife_csid_ver2_hw *csid_hw) struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_ver2_reg_info *csid_reg; uint32_t clk_lvl; + uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; csid_reg = (struct cam_ife_csid_ver2_reg_info *) csid_hw->core_info->csid_reg; @@ -2857,11 +2832,33 @@ static int cam_ife_csid_ver2_enable_core(struct cam_ife_csid_ver2_hw *csid_hw) goto err; } + irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = IFE_CSID_VER2_TOP_IRQ_STATUS_RST; + + csid_hw->reset_irq_handle = cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_0, + irq_mask, + csid_hw, + cam_ife_csid_ver2_reset_irq_top_half, + NULL, + NULL, + NULL); + + if (csid_hw->reset_irq_handle < 1) { + CAM_ERR(CAM_ISP, "csid[%d] reset irq subscribe fail", + csid_hw->hw_intf->hw_idx); + goto disable_res; + } + + reinit_completion(&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]); cam_ife_csid_ver2_program_top(csid_hw); csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP; return rc; +disable_res: + cam_ife_csid_disable_soc_resources(soc_info); + err: CAM_ERR(CAM_ISP, "CSID[%d] init hw fail rc %d", csid_hw->hw_intf->hw_idx, rc); @@ -2872,7 +2869,6 @@ err: static int cam_ife_csid_ver2_enable_hw( struct cam_ife_csid_ver2_hw *csid_hw) { - struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_ver2_reg_info *csid_reg = NULL; uint32_t val; @@ -2976,7 +2972,6 @@ end: return rc; } - static int cam_ife_csid_ver2_disable_core( struct cam_ife_csid_ver2_hw *csid_hw) { @@ -3006,6 +3001,13 @@ static int cam_ife_csid_ver2_disable_core( cam_io_w_mb(0, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->top_irq_mask_addr); + if (csid_hw->reset_irq_handle) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->reset_irq_handle); + csid_hw->reset_irq_handle = 0; + } + rc = cam_ife_csid_disable_soc_resources(soc_info); if (rc) CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed", @@ -3166,6 +3168,7 @@ int cam_ife_csid_ver2_stop(void *hw_priv, int rc = 0; uint32_t i; struct cam_csid_hw_stop_args *csid_stop; + struct cam_csid_reset_cfg_args reset = {0}; if (!hw_priv || !stop_args || (arg_size != sizeof(struct cam_csid_hw_stop_args))) { @@ -3199,6 +3202,10 @@ int cam_ife_csid_ver2_stop(void *hw_priv, } mutex_unlock(&csid_hw->hw_info->hw_mutex); + reset.reset_type = CAM_IFE_CSID_RESET_PATH; + cam_ife_csid_ver2_reset(hw_priv, &reset, + sizeof(struct cam_csid_reset_cfg_args)); + return rc; } @@ -3765,6 +3772,8 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_CSID_MUP_UPDATE: rc = cam_ife_csid_ver2_set_mup_config(csid_hw, cmd_args); break; + case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE: + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type);