Loading drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c +27 −2 Original line number Diff line number Diff line Loading @@ -93,6 +93,8 @@ int cam_bps_init_hw(void *device_priv, CAM_ERR(CAM_ICP, "cpas stop is failed"); else core_info->cpas_start = false; } else { core_info->clk_enable = true; } return rc; Loading @@ -119,9 +121,10 @@ int cam_bps_deinit_hw(void *device_priv, return -EINVAL; } rc = cam_bps_disable_soc_resources(soc_info); rc = cam_bps_disable_soc_resources(soc_info, core_info->clk_enable); if (rc) CAM_ERR(CAM_ICP, "soc disable is failed: %d", rc); core_info->clk_enable = false; if (core_info->cpas_start) { if (cam_cpas_stop(core_info->cpas_handle)) Loading Loading @@ -276,9 +279,31 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type, uint32_t clk_rate = *(uint32_t *)cmd_args; CAM_DBG(CAM_ICP, "bps_src_clk rate = %d", (int)clk_rate); if (!core_info->clk_enable) { cam_bps_handle_pc(bps_dev); cam_cpas_reg_write(core_info->cpas_handle, CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, 0x0); rc = cam_bps_toggle_clk(soc_info, true); if (rc) CAM_ERR(CAM_ICP, "Enable failed"); else core_info->clk_enable = true; rc = cam_bps_handle_resume(bps_dev); if (rc) CAM_ERR(CAM_ICP, "handle resume failed"); } CAM_DBG(CAM_ICP, "clock rate %d", clk_rate); rc = cam_bps_update_clk_rate(soc_info, clk_rate); if (rc) CAM_ERR(CAM_ICP, "Failed to update clk"); } break; case CAM_ICP_BPS_CMD_DISABLE_CLK: if (core_info->clk_enable == true) cam_bps_toggle_clk(soc_info, false); core_info->clk_enable = false; break; default: break; } Loading drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct cam_bps_device_core_info { struct cam_bps_device_hw_info *bps_hw_info; uint32_t cpas_handle; bool cpas_start; bool clk_enable; }; int cam_bps_init_hw(void *device_priv, Loading drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_soc.c +16 −2 Original line number Diff line number Diff line Loading @@ -72,11 +72,13 @@ int cam_bps_enable_soc_resources(struct cam_hw_soc_info *soc_info) return rc; } int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info) int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info, bool disable_clk) { int rc = 0; rc = cam_soc_util_disable_platform_resource(soc_info, true, false); rc = cam_soc_util_disable_platform_resource(soc_info, disable_clk, false); if (rc) CAM_ERR(CAM_ICP, "disable platform failed"); Loading Loading @@ -142,3 +144,15 @@ int cam_bps_update_clk_rate(struct cam_hw_soc_info *soc_info, return cam_soc_util_set_clk_rate(soc_info->clk[soc_info->src_clk_idx], soc_info->clk_name[soc_info->src_clk_idx], clk_rate); } int cam_bps_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable) { int rc = 0; if (clk_enable) rc = cam_soc_util_clk_enable_default(soc_info, CAM_SVS_VOTE); else cam_soc_util_clk_disable_default(soc_info); return rc; } drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_soc.h +3 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,8 @@ int cam_bps_init_soc_resources(struct cam_hw_soc_info *soc_info, int cam_bps_enable_soc_resources(struct cam_hw_soc_info *soc_info); int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info); int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info, bool disable_clk); int cam_bps_get_gdsc_control(struct cam_hw_soc_info *soc_info); Loading @@ -28,4 +29,5 @@ int cam_bps_transfer_gdsc_control(struct cam_hw_soc_info *soc_info); int cam_bps_update_clk_rate(struct cam_hw_soc_info *soc_info, uint32_t clk_rate); int cam_bps_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable); #endif /* _CAM_BPS_SOC_H_*/ drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +143 −10 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ #define ICP_WORKQ_TASK_CMD_TYPE 1 #define ICP_WORKQ_TASK_MSG_TYPE 2 #define ICP_DEV_TYPE_TO_CLK_TYPE(dev_type) \ ((dev_type == CAM_ICP_RES_TYPE_BPS) ? ICP_CLK_HW_BPS : ICP_CLK_HW_IPE) static struct cam_icp_hw_mgr icp_hw_mgr; static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr) Loading Loading @@ -225,6 +228,104 @@ static int cam_icp_clk_idx_from_req_id(struct cam_icp_hw_ctx_data *ctx_data, return 0; } static int cam_icp_ctx_clk_info_init(struct cam_icp_hw_ctx_data *ctx_data) { ctx_data->clk_info.curr_fc = 0; ctx_data->clk_info.base_clk = 0; ctx_data->clk_info.uncompressed_bw = 0; ctx_data->clk_info.compressed_bw = 0; cam_icp_supported_clk_rates(&icp_hw_mgr, ctx_data); return 0; } static int32_t cam_icp_deinit_idle_clk(void *priv, void *data) { struct cam_icp_hw_mgr *hw_mgr = (struct cam_icp_hw_mgr *)priv; struct clk_work_data *task_data = (struct clk_work_data *)data; struct cam_icp_clk_info *clk_info = (struct cam_icp_clk_info *)task_data->data; uint32_t id; uint32_t i; uint32_t curr_clk_rate; struct cam_icp_hw_ctx_data *ctx_data; struct cam_hw_intf *ipe0_dev_intf = NULL; struct cam_hw_intf *ipe1_dev_intf = NULL; struct cam_hw_intf *bps_dev_intf = NULL; struct cam_hw_intf *dev_intf = NULL; ipe0_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][0]; ipe1_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][1]; bps_dev_intf = hw_mgr->devices[CAM_ICP_DEV_BPS][0]; clk_info->base_clk = 0; clk_info->curr_clk = 0; clk_info->over_clked = 0; for (i = 0; i < CAM_ICP_CTX_MAX; i++) { ctx_data = &hw_mgr->ctx_data[i]; mutex_lock(&ctx_data->ctx_mutex); if ((ctx_data->state != CAM_ICP_CTX_STATE_FREE) && (ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data-> icp_dev_acquire_info->dev_type) == clk_info->hw_type)) cam_icp_ctx_clk_info_init(ctx_data); mutex_unlock(&ctx_data->ctx_mutex); } if ((!ipe0_dev_intf) || (!bps_dev_intf)) { CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk"); return -EINVAL; } if (clk_info->hw_type == ICP_CLK_HW_BPS) { dev_intf = bps_dev_intf; id = CAM_ICP_BPS_CMD_DISABLE_CLK; } else if (clk_info->hw_type == ICP_CLK_HW_IPE) { dev_intf = ipe0_dev_intf; id = CAM_ICP_IPE_CMD_DISABLE_CLK; } else { CAM_ERR(CAM_ICP, "Error"); return 0; } CAM_DBG(CAM_ICP, "Disable %d", clk_info->hw_type); dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id, &curr_clk_rate, sizeof(curr_clk_rate)); if (clk_info->hw_type != ICP_CLK_HW_BPS) if (ipe1_dev_intf) ipe1_dev_intf->hw_ops.process_cmd( ipe1_dev_intf->hw_priv, id, &curr_clk_rate, sizeof(curr_clk_rate)); return 0; } static void cam_icp_timer_cb(unsigned long data) { unsigned long flags; struct crm_workq_task *task; struct clk_work_data *task_data; struct cam_req_mgr_timer *timer = (struct cam_req_mgr_timer *)data; spin_lock_irqsave(&icp_hw_mgr.hw_mgr_lock, flags); task = cam_req_mgr_workq_get_task(icp_hw_mgr.msg_work); if (!task) { CAM_ERR(CAM_ICP, "no empty task"); spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags); return; } task_data = (struct clk_work_data *)task->payload; task_data->data = timer->parent; task_data->type = ICP_WORKQ_TASK_MSG_TYPE; task->process_cb = cam_icp_deinit_idle_clk; cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr, CRM_TASK_PRIORITY_0); spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags); } static int cam_icp_clk_info_init(struct cam_icp_hw_mgr *hw_mgr, struct cam_icp_hw_ctx_data *ctx_data) { Loading @@ -237,21 +338,36 @@ static int cam_icp_clk_info_init(struct cam_icp_hw_mgr *hw_mgr, hw_mgr->clk_info[i].over_clked = 0; hw_mgr->clk_info[i].uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW; hw_mgr->clk_info[i].compressed_bw = CAM_CPAS_DEFAULT_AXI_BW; hw_mgr->clk_info[i].hw_type = i; } hw_mgr->icp_default_clk = ICP_CLK_SVS_HZ; return 0; } static int cam_icp_ctx_clk_info_init(struct cam_icp_hw_ctx_data *ctx_data) static int cam_icp_timer_start(struct cam_icp_hw_mgr *hw_mgr) { ctx_data->clk_info.curr_fc = 0; ctx_data->clk_info.base_clk = 0; ctx_data->clk_info.uncompressed_bw = 0; ctx_data->clk_info.compressed_bw = 0; cam_icp_supported_clk_rates(&icp_hw_mgr, ctx_data); int rc = 0; int i; return 0; for (i = 0; i < ICP_CLK_HW_MAX; i++) { if (!hw_mgr->clk_info[i].watch_dog) { rc = crm_timer_init(&hw_mgr->clk_info[i].watch_dog, 3000, &hw_mgr->clk_info[i], &cam_icp_timer_cb); if (rc) CAM_ERR(CAM_ICP, "Failed to start timer %d", i); } } return rc; } static void cam_icp_timer_stop(struct cam_icp_hw_mgr *hw_mgr) { if (!hw_mgr->bps_ctxt_cnt) crm_timer_exit(&hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog); else if (!hw_mgr->ipe_ctxt_cnt) crm_timer_exit(&hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog); } static uint32_t cam_icp_mgr_calc_base_clk(uint32_t frame_cycles, Loading Loading @@ -335,7 +451,6 @@ static bool cam_icp_update_clk_busy(struct cam_icp_hw_mgr *hw_mgr, * no need to update the clock */ mutex_lock(&hw_mgr->hw_mgr_mutex); ctx_data->clk_info.curr_fc = clk_info->frame_cycles; ctx_data->clk_info.base_clk = base_clk; hw_mgr_clk_info->over_clked = 0; if (clk_info->frame_cycles > ctx_data->clk_info.curr_fc) { Loading @@ -360,6 +475,7 @@ static bool cam_icp_update_clk_busy(struct cam_icp_hw_mgr *hw_mgr, rc = true; } } ctx_data->clk_info.curr_fc = clk_info->frame_cycles; mutex_unlock(&hw_mgr->hw_mgr_mutex); return rc; Loading Loading @@ -552,10 +668,15 @@ static bool cam_icp_check_clk_update(struct cam_icp_hw_mgr *hw_mgr, uint64_t req_id; struct cam_icp_clk_info *hw_mgr_clk_info; if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) { crm_timer_reset(hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog); hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS]; else CAM_DBG(CAM_ICP, "Reset bps timer"); } else { crm_timer_reset(hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog); hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE]; CAM_DBG(CAM_ICP, "Reset ipe timer"); } if (icp_hw_mgr.icp_debug_clk) return cam_icp_debug_clk_update(hw_mgr_clk_info); Loading Loading @@ -1009,6 +1130,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL; struct hfi_frame_process_info *hfi_frame_process; struct cam_hw_done_event_data buf_data; uint32_t clk_type; ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr; request_id = ioconfig_ack->user_data2; Loading @@ -1020,6 +1142,10 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) CAM_DBG(CAM_ICP, "ctx : %pK, request_id :%lld", (void *)ctx_data->context_priv, request_id); clk_type = ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->icp_dev_acquire_info-> dev_type); crm_timer_reset(icp_hw_mgr.clk_info[clk_type].watch_dog); mutex_lock(&ctx_data->ctx_mutex); if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) { mutex_unlock(&ctx_data->ctx_mutex); Loading Loading @@ -2754,6 +2880,9 @@ static int cam_icp_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args) } mutex_unlock(&hw_mgr->hw_mgr_mutex); if (!hw_mgr->bps_ctxt_cnt || !hw_mgr->ipe_ctxt_cnt) cam_icp_timer_stop(hw_mgr); return rc; } Loading Loading @@ -3043,6 +3172,10 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) goto ubwc_cfg_failed; } } if (!hw_mgr->bps_ctxt_cnt || !hw_mgr->ipe_ctxt_cnt) cam_icp_timer_start(hw_mgr); rc = cam_icp_mgr_ipe_bps_resume(hw_mgr, ctx_data); if (rc) { mutex_unlock(&hw_mgr->hw_mgr_mutex); Loading Loading
drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c +27 −2 Original line number Diff line number Diff line Loading @@ -93,6 +93,8 @@ int cam_bps_init_hw(void *device_priv, CAM_ERR(CAM_ICP, "cpas stop is failed"); else core_info->cpas_start = false; } else { core_info->clk_enable = true; } return rc; Loading @@ -119,9 +121,10 @@ int cam_bps_deinit_hw(void *device_priv, return -EINVAL; } rc = cam_bps_disable_soc_resources(soc_info); rc = cam_bps_disable_soc_resources(soc_info, core_info->clk_enable); if (rc) CAM_ERR(CAM_ICP, "soc disable is failed: %d", rc); core_info->clk_enable = false; if (core_info->cpas_start) { if (cam_cpas_stop(core_info->cpas_handle)) Loading Loading @@ -276,9 +279,31 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type, uint32_t clk_rate = *(uint32_t *)cmd_args; CAM_DBG(CAM_ICP, "bps_src_clk rate = %d", (int)clk_rate); if (!core_info->clk_enable) { cam_bps_handle_pc(bps_dev); cam_cpas_reg_write(core_info->cpas_handle, CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, 0x0); rc = cam_bps_toggle_clk(soc_info, true); if (rc) CAM_ERR(CAM_ICP, "Enable failed"); else core_info->clk_enable = true; rc = cam_bps_handle_resume(bps_dev); if (rc) CAM_ERR(CAM_ICP, "handle resume failed"); } CAM_DBG(CAM_ICP, "clock rate %d", clk_rate); rc = cam_bps_update_clk_rate(soc_info, clk_rate); if (rc) CAM_ERR(CAM_ICP, "Failed to update clk"); } break; case CAM_ICP_BPS_CMD_DISABLE_CLK: if (core_info->clk_enable == true) cam_bps_toggle_clk(soc_info, false); core_info->clk_enable = false; break; default: break; } Loading
drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct cam_bps_device_core_info { struct cam_bps_device_hw_info *bps_hw_info; uint32_t cpas_handle; bool cpas_start; bool clk_enable; }; int cam_bps_init_hw(void *device_priv, Loading
drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_soc.c +16 −2 Original line number Diff line number Diff line Loading @@ -72,11 +72,13 @@ int cam_bps_enable_soc_resources(struct cam_hw_soc_info *soc_info) return rc; } int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info) int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info, bool disable_clk) { int rc = 0; rc = cam_soc_util_disable_platform_resource(soc_info, true, false); rc = cam_soc_util_disable_platform_resource(soc_info, disable_clk, false); if (rc) CAM_ERR(CAM_ICP, "disable platform failed"); Loading Loading @@ -142,3 +144,15 @@ int cam_bps_update_clk_rate(struct cam_hw_soc_info *soc_info, return cam_soc_util_set_clk_rate(soc_info->clk[soc_info->src_clk_idx], soc_info->clk_name[soc_info->src_clk_idx], clk_rate); } int cam_bps_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable) { int rc = 0; if (clk_enable) rc = cam_soc_util_clk_enable_default(soc_info, CAM_SVS_VOTE); else cam_soc_util_clk_disable_default(soc_info); return rc; }
drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_soc.h +3 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,8 @@ int cam_bps_init_soc_resources(struct cam_hw_soc_info *soc_info, int cam_bps_enable_soc_resources(struct cam_hw_soc_info *soc_info); int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info); int cam_bps_disable_soc_resources(struct cam_hw_soc_info *soc_info, bool disable_clk); int cam_bps_get_gdsc_control(struct cam_hw_soc_info *soc_info); Loading @@ -28,4 +29,5 @@ int cam_bps_transfer_gdsc_control(struct cam_hw_soc_info *soc_info); int cam_bps_update_clk_rate(struct cam_hw_soc_info *soc_info, uint32_t clk_rate); int cam_bps_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable); #endif /* _CAM_BPS_SOC_H_*/
drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +143 −10 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ #define ICP_WORKQ_TASK_CMD_TYPE 1 #define ICP_WORKQ_TASK_MSG_TYPE 2 #define ICP_DEV_TYPE_TO_CLK_TYPE(dev_type) \ ((dev_type == CAM_ICP_RES_TYPE_BPS) ? ICP_CLK_HW_BPS : ICP_CLK_HW_IPE) static struct cam_icp_hw_mgr icp_hw_mgr; static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr) Loading Loading @@ -225,6 +228,104 @@ static int cam_icp_clk_idx_from_req_id(struct cam_icp_hw_ctx_data *ctx_data, return 0; } static int cam_icp_ctx_clk_info_init(struct cam_icp_hw_ctx_data *ctx_data) { ctx_data->clk_info.curr_fc = 0; ctx_data->clk_info.base_clk = 0; ctx_data->clk_info.uncompressed_bw = 0; ctx_data->clk_info.compressed_bw = 0; cam_icp_supported_clk_rates(&icp_hw_mgr, ctx_data); return 0; } static int32_t cam_icp_deinit_idle_clk(void *priv, void *data) { struct cam_icp_hw_mgr *hw_mgr = (struct cam_icp_hw_mgr *)priv; struct clk_work_data *task_data = (struct clk_work_data *)data; struct cam_icp_clk_info *clk_info = (struct cam_icp_clk_info *)task_data->data; uint32_t id; uint32_t i; uint32_t curr_clk_rate; struct cam_icp_hw_ctx_data *ctx_data; struct cam_hw_intf *ipe0_dev_intf = NULL; struct cam_hw_intf *ipe1_dev_intf = NULL; struct cam_hw_intf *bps_dev_intf = NULL; struct cam_hw_intf *dev_intf = NULL; ipe0_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][0]; ipe1_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][1]; bps_dev_intf = hw_mgr->devices[CAM_ICP_DEV_BPS][0]; clk_info->base_clk = 0; clk_info->curr_clk = 0; clk_info->over_clked = 0; for (i = 0; i < CAM_ICP_CTX_MAX; i++) { ctx_data = &hw_mgr->ctx_data[i]; mutex_lock(&ctx_data->ctx_mutex); if ((ctx_data->state != CAM_ICP_CTX_STATE_FREE) && (ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data-> icp_dev_acquire_info->dev_type) == clk_info->hw_type)) cam_icp_ctx_clk_info_init(ctx_data); mutex_unlock(&ctx_data->ctx_mutex); } if ((!ipe0_dev_intf) || (!bps_dev_intf)) { CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk"); return -EINVAL; } if (clk_info->hw_type == ICP_CLK_HW_BPS) { dev_intf = bps_dev_intf; id = CAM_ICP_BPS_CMD_DISABLE_CLK; } else if (clk_info->hw_type == ICP_CLK_HW_IPE) { dev_intf = ipe0_dev_intf; id = CAM_ICP_IPE_CMD_DISABLE_CLK; } else { CAM_ERR(CAM_ICP, "Error"); return 0; } CAM_DBG(CAM_ICP, "Disable %d", clk_info->hw_type); dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id, &curr_clk_rate, sizeof(curr_clk_rate)); if (clk_info->hw_type != ICP_CLK_HW_BPS) if (ipe1_dev_intf) ipe1_dev_intf->hw_ops.process_cmd( ipe1_dev_intf->hw_priv, id, &curr_clk_rate, sizeof(curr_clk_rate)); return 0; } static void cam_icp_timer_cb(unsigned long data) { unsigned long flags; struct crm_workq_task *task; struct clk_work_data *task_data; struct cam_req_mgr_timer *timer = (struct cam_req_mgr_timer *)data; spin_lock_irqsave(&icp_hw_mgr.hw_mgr_lock, flags); task = cam_req_mgr_workq_get_task(icp_hw_mgr.msg_work); if (!task) { CAM_ERR(CAM_ICP, "no empty task"); spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags); return; } task_data = (struct clk_work_data *)task->payload; task_data->data = timer->parent; task_data->type = ICP_WORKQ_TASK_MSG_TYPE; task->process_cb = cam_icp_deinit_idle_clk; cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr, CRM_TASK_PRIORITY_0); spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags); } static int cam_icp_clk_info_init(struct cam_icp_hw_mgr *hw_mgr, struct cam_icp_hw_ctx_data *ctx_data) { Loading @@ -237,21 +338,36 @@ static int cam_icp_clk_info_init(struct cam_icp_hw_mgr *hw_mgr, hw_mgr->clk_info[i].over_clked = 0; hw_mgr->clk_info[i].uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW; hw_mgr->clk_info[i].compressed_bw = CAM_CPAS_DEFAULT_AXI_BW; hw_mgr->clk_info[i].hw_type = i; } hw_mgr->icp_default_clk = ICP_CLK_SVS_HZ; return 0; } static int cam_icp_ctx_clk_info_init(struct cam_icp_hw_ctx_data *ctx_data) static int cam_icp_timer_start(struct cam_icp_hw_mgr *hw_mgr) { ctx_data->clk_info.curr_fc = 0; ctx_data->clk_info.base_clk = 0; ctx_data->clk_info.uncompressed_bw = 0; ctx_data->clk_info.compressed_bw = 0; cam_icp_supported_clk_rates(&icp_hw_mgr, ctx_data); int rc = 0; int i; return 0; for (i = 0; i < ICP_CLK_HW_MAX; i++) { if (!hw_mgr->clk_info[i].watch_dog) { rc = crm_timer_init(&hw_mgr->clk_info[i].watch_dog, 3000, &hw_mgr->clk_info[i], &cam_icp_timer_cb); if (rc) CAM_ERR(CAM_ICP, "Failed to start timer %d", i); } } return rc; } static void cam_icp_timer_stop(struct cam_icp_hw_mgr *hw_mgr) { if (!hw_mgr->bps_ctxt_cnt) crm_timer_exit(&hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog); else if (!hw_mgr->ipe_ctxt_cnt) crm_timer_exit(&hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog); } static uint32_t cam_icp_mgr_calc_base_clk(uint32_t frame_cycles, Loading Loading @@ -335,7 +451,6 @@ static bool cam_icp_update_clk_busy(struct cam_icp_hw_mgr *hw_mgr, * no need to update the clock */ mutex_lock(&hw_mgr->hw_mgr_mutex); ctx_data->clk_info.curr_fc = clk_info->frame_cycles; ctx_data->clk_info.base_clk = base_clk; hw_mgr_clk_info->over_clked = 0; if (clk_info->frame_cycles > ctx_data->clk_info.curr_fc) { Loading @@ -360,6 +475,7 @@ static bool cam_icp_update_clk_busy(struct cam_icp_hw_mgr *hw_mgr, rc = true; } } ctx_data->clk_info.curr_fc = clk_info->frame_cycles; mutex_unlock(&hw_mgr->hw_mgr_mutex); return rc; Loading Loading @@ -552,10 +668,15 @@ static bool cam_icp_check_clk_update(struct cam_icp_hw_mgr *hw_mgr, uint64_t req_id; struct cam_icp_clk_info *hw_mgr_clk_info; if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) { crm_timer_reset(hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog); hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS]; else CAM_DBG(CAM_ICP, "Reset bps timer"); } else { crm_timer_reset(hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog); hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE]; CAM_DBG(CAM_ICP, "Reset ipe timer"); } if (icp_hw_mgr.icp_debug_clk) return cam_icp_debug_clk_update(hw_mgr_clk_info); Loading Loading @@ -1009,6 +1130,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL; struct hfi_frame_process_info *hfi_frame_process; struct cam_hw_done_event_data buf_data; uint32_t clk_type; ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr; request_id = ioconfig_ack->user_data2; Loading @@ -1020,6 +1142,10 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) CAM_DBG(CAM_ICP, "ctx : %pK, request_id :%lld", (void *)ctx_data->context_priv, request_id); clk_type = ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->icp_dev_acquire_info-> dev_type); crm_timer_reset(icp_hw_mgr.clk_info[clk_type].watch_dog); mutex_lock(&ctx_data->ctx_mutex); if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) { mutex_unlock(&ctx_data->ctx_mutex); Loading Loading @@ -2754,6 +2880,9 @@ static int cam_icp_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args) } mutex_unlock(&hw_mgr->hw_mgr_mutex); if (!hw_mgr->bps_ctxt_cnt || !hw_mgr->ipe_ctxt_cnt) cam_icp_timer_stop(hw_mgr); return rc; } Loading Loading @@ -3043,6 +3172,10 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) goto ubwc_cfg_failed; } } if (!hw_mgr->bps_ctxt_cnt || !hw_mgr->ipe_ctxt_cnt) cam_icp_timer_start(hw_mgr); rc = cam_icp_mgr_ipe_bps_resume(hw_mgr, ctx_data); if (rc) { mutex_unlock(&hw_mgr->hw_mgr_mutex); Loading