Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +54 −1 Original line number Diff line number Diff line Loading @@ -824,6 +824,47 @@ static void cam_ife_hw_mgr_dump_acq_data( } } static int cam_ife_mgr_csid_change_halt_mode(struct list_head *halt_list, uint32_t base_idx, enum cam_ife_csid_halt_mode halt_mode) { struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_isp_resource_node *isp_res; struct cam_csid_hw_halt_args halt; struct cam_hw_intf *hw_intf; uint32_t i; int rc = 0; list_for_each_entry(hw_mgr_res, halt_list, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i] || (hw_mgr_res->hw_res[i]->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) continue; isp_res = hw_mgr_res->hw_res[i]; if (isp_res->hw_intf->hw_idx != base_idx) continue; if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) && (isp_res->res_id == CAM_IFE_PIX_PATH_RES_IPP)) { hw_intf = isp_res->hw_intf; halt.node_res = isp_res; halt.halt_mode = halt_mode; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE, &halt, sizeof(struct cam_csid_hw_halt_args)); if (rc) CAM_ERR(CAM_ISP, "Halt update failed"); break; } } } return rc; } static int cam_ife_mgr_csid_stop_hw( struct cam_ife_hw_mgr_ctx *ctx, struct list_head *stop_list, uint32_t base_idx, uint32_t stop_cmd) Loading Loading @@ -3864,6 +3905,19 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) */ if (i == ctx->num_base) master_base_idx = ctx->base[0].idx; /*Change slave mode*/ if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY) { for (i = 0; i < ctx->num_base; i++) { if (ctx->base[i].idx == master_base_idx) continue; cam_ife_mgr_csid_change_halt_mode( &ctx->res_list_ife_csid, ctx->base[i].idx, CAM_CSID_HALT_MODE_INTERNAL); } } CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx); /* Stop the master CSID path first */ Loading Loading @@ -6954,7 +7008,6 @@ static int cam_ife_hw_mgr_handle_hw_rup( CAM_DBG(CAM_ISP, "RUP done for VFE:%d source %d", event_info->hw_idx, event_info->res_id); return 0; } Loading drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +96 −0 Original line number Diff line number Diff line Loading @@ -2127,6 +2127,64 @@ static int cam_ife_csid_enable_pxl_path( return 0; } static void cam_ife_csid_change_pxl_halt_mode( struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res, enum cam_ife_csid_halt_mode halt_mode) { uint32_t val = 0; const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; struct cam_ife_csid_path_cfg *path_data; const struct cam_ife_csid_pxl_reg_offset *pxl_reg; bool is_ipp; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d", csid_hw->hw_intf->hw_idx, res->res_id); goto end; } if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW || res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { CAM_ERR(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d", csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); goto end; } if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { is_ipp = true; pxl_reg = csid_reg->ipp_reg; } else { goto end; } if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { CAM_ERR(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d", csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", res->res_id, res->res_state); goto end; } cam_io_w_mb(0, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_irq_mask_addr); /* configure Halt for slave */ val = cam_io_r_mb(soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr); val &= ~0xC; val |= (halt_mode << 2); cam_io_w_mb(val, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr); end: return; } static int cam_ife_csid_disable_pxl_path( struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res, Loading Loading @@ -3692,6 +3750,41 @@ int cam_ife_csid_start(void *hw_priv, void *start_args, return rc; } int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw, void *halt_args) { struct cam_isp_resource_node *res; struct cam_csid_hw_halt_args *csid_halt; if (!csid_hw || !halt_args) { CAM_ERR(CAM_ISP, "CSID: Invalid args"); return -EINVAL; } csid_halt = (struct cam_csid_hw_halt_args *)halt_args; /* Change the halt mode */ res = csid_halt->node_res; CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); switch (res->res_type) { case CAM_ISP_RESOURCE_PIX_PATH: if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) cam_ife_csid_change_pxl_halt_mode(csid_hw, res, csid_halt->halt_mode); break; default: CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", csid_hw->hw_intf->hw_idx, res->res_type); break; } return 0; } int cam_ife_csid_stop(void *hw_priv, void *stop_args, uint32_t arg_size) { Loading Loading @@ -4089,6 +4182,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args); break; case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE: rc = cam_ife_csid_halt(csid_hw, cmd_args); break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); Loading drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +27 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,33 @@ enum cam_ife_csid_halt_cmd { CAM_CSID_HALT_MAX, }; /** * enum cam_ife_csid_halt_mode_cmd - Specify the halt command type */ enum cam_ife_csid_halt_mode { CAM_CSID_HALT_MODE_INTERNAL, CAM_CSID_HALT_MODE_GLOBAL, CAM_CSID_HALT_MODE_MASTER, CAM_CSID_HALT_MODE_SLAVE, CAM_CSID_HALT_MODE_MAX, }; /** * struct cam_csid_hw_halt_args * @halt_mode : Applicable only for PATH resources * 0 Internal : The CSID responds to the HALT_CMD * 1 Global : The CSID responds to the GLOBAL_HALT_CMD * 2 Master : The CSID responds to the HALT_CMD * 3 Slave : The CSID responds to the external halt command * and not the HALT_CMD register * @node_res : reource pointer array( ie cid or CSID) * */ struct cam_csid_hw_halt_args { enum cam_ife_csid_halt_mode halt_mode; struct cam_isp_resource_node *node_res; }; /** * struct cam_csid_hw_stop- stop all resources * @stop_cmd : Applicable only for PATH resources Loading drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, CAM_ISP_HW_CMD_DUMP_HW, CAM_ISP_HW_CMD_FE_TRIGGER_CMD, CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE, CAM_ISP_HW_CMD_MAX, }; Loading Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +54 −1 Original line number Diff line number Diff line Loading @@ -824,6 +824,47 @@ static void cam_ife_hw_mgr_dump_acq_data( } } static int cam_ife_mgr_csid_change_halt_mode(struct list_head *halt_list, uint32_t base_idx, enum cam_ife_csid_halt_mode halt_mode) { struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_isp_resource_node *isp_res; struct cam_csid_hw_halt_args halt; struct cam_hw_intf *hw_intf; uint32_t i; int rc = 0; list_for_each_entry(hw_mgr_res, halt_list, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i] || (hw_mgr_res->hw_res[i]->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) continue; isp_res = hw_mgr_res->hw_res[i]; if (isp_res->hw_intf->hw_idx != base_idx) continue; if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) && (isp_res->res_id == CAM_IFE_PIX_PATH_RES_IPP)) { hw_intf = isp_res->hw_intf; halt.node_res = isp_res; halt.halt_mode = halt_mode; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE, &halt, sizeof(struct cam_csid_hw_halt_args)); if (rc) CAM_ERR(CAM_ISP, "Halt update failed"); break; } } } return rc; } static int cam_ife_mgr_csid_stop_hw( struct cam_ife_hw_mgr_ctx *ctx, struct list_head *stop_list, uint32_t base_idx, uint32_t stop_cmd) Loading Loading @@ -3864,6 +3905,19 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) */ if (i == ctx->num_base) master_base_idx = ctx->base[0].idx; /*Change slave mode*/ if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY) { for (i = 0; i < ctx->num_base; i++) { if (ctx->base[i].idx == master_base_idx) continue; cam_ife_mgr_csid_change_halt_mode( &ctx->res_list_ife_csid, ctx->base[i].idx, CAM_CSID_HALT_MODE_INTERNAL); } } CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx); /* Stop the master CSID path first */ Loading Loading @@ -6954,7 +7008,6 @@ static int cam_ife_hw_mgr_handle_hw_rup( CAM_DBG(CAM_ISP, "RUP done for VFE:%d source %d", event_info->hw_idx, event_info->res_id); return 0; } Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +96 −0 Original line number Diff line number Diff line Loading @@ -2127,6 +2127,64 @@ static int cam_ife_csid_enable_pxl_path( return 0; } static void cam_ife_csid_change_pxl_halt_mode( struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res, enum cam_ife_csid_halt_mode halt_mode) { uint32_t val = 0; const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; struct cam_ife_csid_path_cfg *path_data; const struct cam_ife_csid_pxl_reg_offset *pxl_reg; bool is_ipp; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d", csid_hw->hw_intf->hw_idx, res->res_id); goto end; } if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW || res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { CAM_ERR(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d", csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); goto end; } if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { is_ipp = true; pxl_reg = csid_reg->ipp_reg; } else { goto end; } if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { CAM_ERR(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d", csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", res->res_id, res->res_state); goto end; } cam_io_w_mb(0, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_irq_mask_addr); /* configure Halt for slave */ val = cam_io_r_mb(soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr); val &= ~0xC; val |= (halt_mode << 2); cam_io_w_mb(val, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr); end: return; } static int cam_ife_csid_disable_pxl_path( struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res, Loading Loading @@ -3692,6 +3750,41 @@ int cam_ife_csid_start(void *hw_priv, void *start_args, return rc; } int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw, void *halt_args) { struct cam_isp_resource_node *res; struct cam_csid_hw_halt_args *csid_halt; if (!csid_hw || !halt_args) { CAM_ERR(CAM_ISP, "CSID: Invalid args"); return -EINVAL; } csid_halt = (struct cam_csid_hw_halt_args *)halt_args; /* Change the halt mode */ res = csid_halt->node_res; CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); switch (res->res_type) { case CAM_ISP_RESOURCE_PIX_PATH: if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) cam_ife_csid_change_pxl_halt_mode(csid_hw, res, csid_halt->halt_mode); break; default: CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", csid_hw->hw_intf->hw_idx, res->res_type); break; } return 0; } int cam_ife_csid_stop(void *hw_priv, void *stop_args, uint32_t arg_size) { Loading Loading @@ -4089,6 +4182,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args); break; case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE: rc = cam_ife_csid_halt(csid_hw, cmd_args); break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +27 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,33 @@ enum cam_ife_csid_halt_cmd { CAM_CSID_HALT_MAX, }; /** * enum cam_ife_csid_halt_mode_cmd - Specify the halt command type */ enum cam_ife_csid_halt_mode { CAM_CSID_HALT_MODE_INTERNAL, CAM_CSID_HALT_MODE_GLOBAL, CAM_CSID_HALT_MODE_MASTER, CAM_CSID_HALT_MODE_SLAVE, CAM_CSID_HALT_MODE_MAX, }; /** * struct cam_csid_hw_halt_args * @halt_mode : Applicable only for PATH resources * 0 Internal : The CSID responds to the HALT_CMD * 1 Global : The CSID responds to the GLOBAL_HALT_CMD * 2 Master : The CSID responds to the HALT_CMD * 3 Slave : The CSID responds to the external halt command * and not the HALT_CMD register * @node_res : reource pointer array( ie cid or CSID) * */ struct cam_csid_hw_halt_args { enum cam_ife_csid_halt_mode halt_mode; struct cam_isp_resource_node *node_res; }; /** * struct cam_csid_hw_stop- stop all resources * @stop_cmd : Applicable only for PATH resources Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, CAM_ISP_HW_CMD_DUMP_HW, CAM_ISP_HW_CMD_FE_TRIGGER_CMD, CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE, CAM_ISP_HW_CMD_MAX, }; Loading