diff options
Diffstat (limited to 'drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c')
-rw-r--r-- | drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 42daa02..c70ee14 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -2128,6 +2128,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, @@ -3693,6 +3751,41 @@ end: 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) { @@ -4090,6 +4183,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); |