diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c index b994fb3414..ea00f91d4a 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c @@ -3104,6 +3104,90 @@ static int cam_ife_csid_poll_stop_status( return rc; } +static int cam_ife_csid_change_pxl_halt_mode( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_hw_halt_args *csid_halt) +{ + uint32_t val = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + struct cam_isp_resource_node *res; + + res = csid_halt->node_res; + + csid_reg = csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_id != CAM_IFE_PIX_PATH_RES_IPP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res id %d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { + CAM_ERR(CAM_ISP, "CSID:%d Res:%d in invalid state:%d", + csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); + return -EINVAL; + } + + + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_mask_addr); + + /* configure Halt for slave */ + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->ctrl_addr); + val &= ~0xC; + val |= (csid_halt->halt_mode << 2); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->ctrl_addr); + CAM_DBG(CAM_ISP, "CSID:%d IPP path Res halt mode:%d configured:%x", + csid_hw->hw_intf->hw_idx, csid_halt->halt_mode, val); + + return 0; +} + +int cam_ife_csid_halt(struct cam_ife_csid_ver1_hw *csid_hw, + void *halt_args) +{ + struct cam_isp_resource_node *res; + struct cam_ife_csid_hw_halt_args *csid_halt; + int rc = 0; + + if (!csid_hw || !halt_args) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + csid_halt = (struct cam_ife_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); + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type %d", + csid_hw->hw_intf->hw_idx, + res->res_type); + return -EINVAL; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + rc = cam_ife_csid_change_pxl_halt_mode(csid_hw, csid_halt); + break; + default: + CAM_DBG(CAM_ISP, "CSID:%d res_id %d", + csid_hw->hw_intf->hw_idx, + res->res_id); + break; + } + + return rc; +} + int cam_ife_csid_ver1_stop(void *hw_priv, void *stop_args, uint32_t arg_size) { @@ -3728,6 +3812,9 @@ static int cam_ife_csid_ver1_process_cmd(void *hw_priv, case CAM_IFE_CSID_LOG_ACQUIRE_DATA: cam_ife_csid_log_acquire_data(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);