Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +50 −3 Original line number Diff line number Diff line Loading @@ -2164,6 +2164,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) } CAM_DBG(CAM_ISP, "START CID SRC ... in ctx id:%d", ctx->ctx_index); ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Exit...(success)"); return 0; Loading Loading @@ -2419,6 +2420,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, memset(ctx->base, 0, sizeof(ctx->base)); /* release cdm handle */ ctx->dual_ife_irq_mismatch_cnt = 0; cam_cdm_release(ctx->cdm_handle); /* clean context */ Loading Loading @@ -3004,6 +3006,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 @@ -3654,13 +3686,28 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE cound not generate hw event %d", hw_event_type); 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); 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", hw_event_type); Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +34 −30 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 @@ -121,11 +121,14 @@ 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 * @overflow_pending flag to specify the overflow is pending for the * context * @is_rdi_only_context flag to specify the context has only rdi resource * @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 * @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 @@ -160,6 +163,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t is_rdi_only_context; struct completion config_done_complete; bool init_done; 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 +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 @@ -97,6 +97,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_GET_REG_DUMP, CAM_ISP_HW_CMD_SOF_IRQ_DEBUG, CAM_ISP_HW_CMD_SET_CAMIF_DEBUG, 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 @@ -696,6 +696,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 drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +38 −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 @@ -378,6 +378,40 @@ static int cam_vfe_camif_reg_dump( return rc; } static int cam_vfe_camif_irq_reg_dump( struct cam_isp_resource_node *camif_res) { struct cam_vfe_mux_camif_data *camif_priv; struct cam_vfe_soc_private *soc_private; int rc = 0; if (!camif_res) { CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n"); return -EINVAL; } if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) || (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) { CAM_ERR(CAM_ISP, "Error! Invalid state\n"); return 0; } camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv; soc_private = camif_priv->soc_info->soc_private; CAM_INFO(CAM_ISP, "Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", camif_priv->hw_intf->hw_idx, 0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c), 0x60, cam_io_r_mb(camif_priv->mem_base + 0x60)); CAM_INFO(CAM_ISP, "Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", camif_priv->hw_intf->hw_idx, 0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c), 0x70, cam_io_r_mb(camif_priv->mem_base + 0x70)); return rc; } static int cam_vfe_camif_resource_stop( struct cam_isp_resource_node *camif_res) { Loading Loading @@ -465,6 +499,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; camif_priv->camif_debug = *((uint32_t *)cmd_args); break; case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = cam_vfe_camif_irq_reg_dump(rsrc_node); break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); Loading Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +50 −3 Original line number Diff line number Diff line Loading @@ -2164,6 +2164,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) } CAM_DBG(CAM_ISP, "START CID SRC ... in ctx id:%d", ctx->ctx_index); ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Exit...(success)"); return 0; Loading Loading @@ -2419,6 +2420,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, memset(ctx->base, 0, sizeof(ctx->base)); /* release cdm handle */ ctx->dual_ife_irq_mismatch_cnt = 0; cam_cdm_release(ctx->cdm_handle); /* clean context */ Loading Loading @@ -3004,6 +3006,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 @@ -3654,13 +3686,28 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE cound not generate hw event %d", hw_event_type); 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); 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", hw_event_type); Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +34 −30 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 @@ -121,11 +121,14 @@ 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 * @overflow_pending flag to specify the overflow is pending for the * context * @is_rdi_only_context flag to specify the context has only rdi resource * @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 * @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 @@ -160,6 +163,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t is_rdi_only_context; struct completion config_done_complete; bool init_done; 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 +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 @@ -97,6 +97,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_GET_REG_DUMP, CAM_ISP_HW_CMD_SOF_IRQ_DEBUG, CAM_ISP_HW_CMD_SET_CAMIF_DEBUG, 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 @@ -696,6 +696,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
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +38 −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 @@ -378,6 +378,40 @@ static int cam_vfe_camif_reg_dump( return rc; } static int cam_vfe_camif_irq_reg_dump( struct cam_isp_resource_node *camif_res) { struct cam_vfe_mux_camif_data *camif_priv; struct cam_vfe_soc_private *soc_private; int rc = 0; if (!camif_res) { CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n"); return -EINVAL; } if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) || (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) { CAM_ERR(CAM_ISP, "Error! Invalid state\n"); return 0; } camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv; soc_private = camif_priv->soc_info->soc_private; CAM_INFO(CAM_ISP, "Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", camif_priv->hw_intf->hw_idx, 0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c), 0x60, cam_io_r_mb(camif_priv->mem_base + 0x60)); CAM_INFO(CAM_ISP, "Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", camif_priv->hw_intf->hw_idx, 0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c), 0x70, cam_io_r_mb(camif_priv->mem_base + 0x70)); return rc; } static int cam_vfe_camif_resource_stop( struct cam_isp_resource_node *camif_res) { Loading Loading @@ -465,6 +499,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; camif_priv->camif_debug = *((uint32_t *)cmd_args); break; case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = cam_vfe_camif_irq_reg_dump(rsrc_node); break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); Loading