Loading drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +60 −17 Original line number Diff line number Diff line Loading @@ -1293,6 +1293,44 @@ static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr, return rc; } static int cam_icp_mgr_ipe_bps_get_gdsc_control( struct cam_icp_hw_mgr *hw_mgr) { int rc = 0; struct cam_hw_intf *ipe0_dev_intf = NULL; struct cam_hw_intf *ipe1_dev_intf = NULL; struct cam_hw_intf *bps_dev_intf = NULL; ipe0_dev_intf = hw_mgr->ipe0_dev_intf; ipe1_dev_intf = hw_mgr->ipe1_dev_intf; bps_dev_intf = hw_mgr->bps_dev_intf; if ((!ipe0_dev_intf) || (!bps_dev_intf)) { CAM_ERR(CAM_ICP, "dev intfs are wrong"); return -EINVAL; } if (icp_hw_mgr.ipe_bps_pc_flag) { rc = bps_dev_intf->hw_ops.process_cmd( bps_dev_intf->hw_priv, CAM_ICP_BPS_CMD_POWER_COLLAPSE, NULL, 0); rc = ipe0_dev_intf->hw_ops.process_cmd( ipe0_dev_intf->hw_priv, CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0); if (ipe1_dev_intf) { rc = ipe1_dev_intf->hw_ops.process_cmd( ipe1_dev_intf->hw_priv, CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0); } } return rc; } static int cam_icp_set_dbg_default_clk(void *data, u64 val) { icp_hw_mgr.icp_debug_clk = val; Loading Loading @@ -1817,13 +1855,16 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr) ipe1_dev_intf = hw_mgr->ipe1_dev_intf; bps_dev_intf = hw_mgr->bps_dev_intf; if (hw_mgr->bps_ctxt_cnt) { rc = bps_dev_intf->hw_ops.process_cmd( bps_dev_intf->hw_priv, CAM_ICP_BPS_CMD_RESET, NULL, 0); if (rc) CAM_ERR(CAM_ICP, "bps reset failed"); } if (hw_mgr->ipe_ctxt_cnt) { rc = ipe0_dev_intf->hw_ops.process_cmd( ipe0_dev_intf->hw_priv, CAM_ICP_IPE_CMD_RESET, Loading @@ -1839,6 +1880,7 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr) if (rc) CAM_ERR(CAM_ICP, "ipe1 reset failed"); } } return 0; } Loading @@ -1858,6 +1900,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr) sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva; CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg); cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr); cam_icp_ipebps_reset(hw_mgr); atomic_set(&hw_mgr->recovery, 1); Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +49 −2 Original line number Diff line number Diff line Loading @@ -2984,6 +2984,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) } } ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index); Loading Loading @@ -3066,6 +3067,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, ctx->is_rdi_only_context = 0; ctx->cdm_handle = 0; ctx->cdm_ops = NULL; ctx->dual_ife_irq_mismatch_cnt = 0; atomic_set(&ctx->overflow_pending, 0); for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { ctx->sof_cnt[i] = 0; Loading Loading @@ -4078,6 +4080,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, } } static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx) { struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_isp_hw_get_cmd_update cmd_update; int i = 0; list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) continue; for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; switch (hw_mgr_res->hw_res[i]->res_id) { case CAM_ISP_HW_VFE_IN_CAMIF: hw_intf = hw_mgr_res->hw_res[i]->hw_intf; cmd_update.res = hw_mgr_res->hw_res[i]; cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP; hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, &cmd_update, sizeof(cmd_update)); break; default: break; } } } } static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; Loading Loading @@ -4748,11 +4780,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) { rc = -1; return rc; } CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE could not generate hw event %d", hw_event_type); rc = -1; return rc; if (event_cnt[core_idx0] >= 2) { event_cnt[core_idx0]--; ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; } if (event_cnt[core_idx1] >= 2) { event_cnt[core_idx1]--; ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; } if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1) cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx); rc = 0; } CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +37 −32 Original line number Diff line number Diff line Loading @@ -127,13 +127,17 @@ struct cam_ife_hw_mgr_debug { * @sof_cnt sof count value per core, used for dual VFE * @epoch_cnt epoch count value per core, used for dual VFE * @eof_cnt eof count value per core, used for dual VFE * @overflow_pending flat to specify the overflow is pending for the * context * @is_rdi_only_context flag to specify the context has only rdi resource * @overflow_pending flat to specify the overflow is pending * for the context * @is_rdi_only_context flag to specify the context has only rdi * resource * @config_done_complete indicator for configuration complete * @init_done indicate whether init hw is done * @is_fe_enable indicate whether fetch engine\read path is enabled * @is_fe_enable indicate whether fetch engine\read path * is enabled * @res_bitmap fill resource bitmap for which rup to be set * @dual_ife_irq_mismatch_cnt irq mismatch count value per core, used for * dual VFE */ struct cam_ife_hw_mgr_ctx { struct list_head list; Loading Loading @@ -171,6 +175,7 @@ struct cam_ife_hw_mgr_ctx { bool init_done; bool is_fe_enable; unsigned long res_bitmap; uint32_t dual_ife_irq_mismatch_cnt; }; /** Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_MAX, }; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CLOCK_UPDATE: case CAM_ISP_HW_CMD_BW_UPDATE: case CAM_ISP_HW_CMD_BW_CONTROL: case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); Loading Loading
drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +60 −17 Original line number Diff line number Diff line Loading @@ -1293,6 +1293,44 @@ static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr, return rc; } static int cam_icp_mgr_ipe_bps_get_gdsc_control( struct cam_icp_hw_mgr *hw_mgr) { int rc = 0; struct cam_hw_intf *ipe0_dev_intf = NULL; struct cam_hw_intf *ipe1_dev_intf = NULL; struct cam_hw_intf *bps_dev_intf = NULL; ipe0_dev_intf = hw_mgr->ipe0_dev_intf; ipe1_dev_intf = hw_mgr->ipe1_dev_intf; bps_dev_intf = hw_mgr->bps_dev_intf; if ((!ipe0_dev_intf) || (!bps_dev_intf)) { CAM_ERR(CAM_ICP, "dev intfs are wrong"); return -EINVAL; } if (icp_hw_mgr.ipe_bps_pc_flag) { rc = bps_dev_intf->hw_ops.process_cmd( bps_dev_intf->hw_priv, CAM_ICP_BPS_CMD_POWER_COLLAPSE, NULL, 0); rc = ipe0_dev_intf->hw_ops.process_cmd( ipe0_dev_intf->hw_priv, CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0); if (ipe1_dev_intf) { rc = ipe1_dev_intf->hw_ops.process_cmd( ipe1_dev_intf->hw_priv, CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0); } } return rc; } static int cam_icp_set_dbg_default_clk(void *data, u64 val) { icp_hw_mgr.icp_debug_clk = val; Loading Loading @@ -1817,13 +1855,16 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr) ipe1_dev_intf = hw_mgr->ipe1_dev_intf; bps_dev_intf = hw_mgr->bps_dev_intf; if (hw_mgr->bps_ctxt_cnt) { rc = bps_dev_intf->hw_ops.process_cmd( bps_dev_intf->hw_priv, CAM_ICP_BPS_CMD_RESET, NULL, 0); if (rc) CAM_ERR(CAM_ICP, "bps reset failed"); } if (hw_mgr->ipe_ctxt_cnt) { rc = ipe0_dev_intf->hw_ops.process_cmd( ipe0_dev_intf->hw_priv, CAM_ICP_IPE_CMD_RESET, Loading @@ -1839,6 +1880,7 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr) if (rc) CAM_ERR(CAM_ICP, "ipe1 reset failed"); } } return 0; } Loading @@ -1858,6 +1900,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr) sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva; CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg); cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr); cam_icp_ipebps_reset(hw_mgr); atomic_set(&hw_mgr->recovery, 1); Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +49 −2 Original line number Diff line number Diff line Loading @@ -2984,6 +2984,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) } } ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index); Loading Loading @@ -3066,6 +3067,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, ctx->is_rdi_only_context = 0; ctx->cdm_handle = 0; ctx->cdm_ops = NULL; ctx->dual_ife_irq_mismatch_cnt = 0; atomic_set(&ctx->overflow_pending, 0); for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { ctx->sof_cnt[i] = 0; Loading Loading @@ -4078,6 +4080,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, } } static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx) { struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_isp_hw_get_cmd_update cmd_update; int i = 0; list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) continue; for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; switch (hw_mgr_res->hw_res[i]->res_id) { case CAM_ISP_HW_VFE_IN_CAMIF: hw_intf = hw_mgr_res->hw_res[i]->hw_intf; cmd_update.res = hw_mgr_res->hw_res[i]; cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP; hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, &cmd_update, sizeof(cmd_update)); break; default: break; } } } } static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; Loading Loading @@ -4748,11 +4780,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) { rc = -1; return rc; } CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE could not generate hw event %d", hw_event_type); rc = -1; return rc; if (event_cnt[core_idx0] >= 2) { event_cnt[core_idx0]--; ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; } if (event_cnt[core_idx1] >= 2) { event_cnt[core_idx1]--; ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; } if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1) cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx); rc = 0; } CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +37 −32 Original line number Diff line number Diff line Loading @@ -127,13 +127,17 @@ struct cam_ife_hw_mgr_debug { * @sof_cnt sof count value per core, used for dual VFE * @epoch_cnt epoch count value per core, used for dual VFE * @eof_cnt eof count value per core, used for dual VFE * @overflow_pending flat to specify the overflow is pending for the * context * @is_rdi_only_context flag to specify the context has only rdi resource * @overflow_pending flat to specify the overflow is pending * for the context * @is_rdi_only_context flag to specify the context has only rdi * resource * @config_done_complete indicator for configuration complete * @init_done indicate whether init hw is done * @is_fe_enable indicate whether fetch engine\read path is enabled * @is_fe_enable indicate whether fetch engine\read path * is enabled * @res_bitmap fill resource bitmap for which rup to be set * @dual_ife_irq_mismatch_cnt irq mismatch count value per core, used for * dual VFE */ struct cam_ife_hw_mgr_ctx { struct list_head list; Loading Loading @@ -171,6 +175,7 @@ struct cam_ife_hw_mgr_ctx { bool init_done; bool is_fe_enable; unsigned long res_bitmap; uint32_t dual_ife_irq_mismatch_cnt; }; /** Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_MAX, }; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CLOCK_UPDATE: case CAM_ISP_HW_CMD_BW_UPDATE: case CAM_ISP_HW_CMD_BW_CONTROL: case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); Loading