|
@@ -1246,6 +1246,63 @@ static int cam_tfe_csid_enable_pxl_path(
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void cam_tfe_csid_change_pxl_halt_mode(
|
|
|
|
+ struct cam_tfe_csid_hw *csid_hw,
|
|
|
|
+ struct cam_isp_resource_node *res,
|
|
|
|
+ enum cam_tfe_csid_halt_mode halt_mode)
|
|
|
|
+{
|
|
|
|
+ uint32_t val = 0;
|
|
|
|
+ const struct cam_tfe_csid_reg_offset *csid_reg;
|
|
|
|
+ struct cam_hw_soc_info *soc_info;
|
|
|
|
+ struct cam_tfe_csid_path_cfg *path_data;
|
|
|
|
+ const struct cam_tfe_csid_pxl_reg_offset *pxl_reg;
|
|
|
|
+ bool is_ipp;
|
|
|
|
+
|
|
|
|
+ path_data = (struct cam_tfe_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_TFE_CSID_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_TFE_CSID_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, "IPP",
|
|
|
|
+ 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_tfe_csid_disable_pxl_path(
|
|
static int cam_tfe_csid_disable_pxl_path(
|
|
struct cam_tfe_csid_hw *csid_hw,
|
|
struct cam_tfe_csid_hw *csid_hw,
|
|
struct cam_isp_resource_node *res,
|
|
struct cam_isp_resource_node *res,
|
|
@@ -2088,6 +2145,41 @@ end:
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int cam_tfe_csid_halt(struct cam_tfe_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_TFE_CSID_PATH_RES_IPP)
|
|
|
|
+ cam_tfe_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;
|
|
|
|
+}
|
|
|
|
+
|
|
static int cam_tfe_csid_stop(void *hw_priv,
|
|
static int cam_tfe_csid_stop(void *hw_priv,
|
|
void *stop_args, uint32_t arg_size)
|
|
void *stop_args, uint32_t arg_size)
|
|
{
|
|
{
|
|
@@ -2095,7 +2187,7 @@ static int cam_tfe_csid_stop(void *hw_priv,
|
|
struct cam_tfe_csid_hw *csid_hw;
|
|
struct cam_tfe_csid_hw *csid_hw;
|
|
struct cam_hw_info *csid_hw_info;
|
|
struct cam_hw_info *csid_hw_info;
|
|
struct cam_isp_resource_node *res;
|
|
struct cam_isp_resource_node *res;
|
|
- struct cam_tfe_csid_hw_stop_args *csid_stop;
|
|
|
|
|
|
+ struct cam_tfe_csid_hw_stop_args *csid_stop;
|
|
uint32_t i;
|
|
uint32_t i;
|
|
uint32_t res_mask = 0;
|
|
uint32_t res_mask = 0;
|
|
|
|
|
|
@@ -2472,6 +2564,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv,
|
|
case CAM_ISP_HW_CMD_DUMP_HW:
|
|
case CAM_ISP_HW_CMD_DUMP_HW:
|
|
rc = cam_tfe_csid_dump_hw(csid_hw, cmd_args);
|
|
rc = cam_tfe_csid_dump_hw(csid_hw, cmd_args);
|
|
break;
|
|
break;
|
|
|
|
+ case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE:
|
|
|
|
+ rc = cam_tfe_csid_halt(csid_hw, cmd_args);
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
|
|
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
|
|
csid_hw->hw_intf->hw_idx, cmd_type);
|
|
csid_hw->hw_intf->hw_idx, cmd_type);
|