From d2461de353968d900cd07a7bae5fc956144e428e Mon Sep 17 00:00:00 2001 From: Karthik Anantha Ram Date: Fri, 7 Aug 2020 15:00:29 -0700 Subject: [PATCH] msm: camera: isp: Add support for TPG cfg blob TPG core cfg data is sent by userspace as a blob. Add support to configure the same at stream on. CRs-Fixed: 2772256 Change-Id: I94b9e3fd8aaf02e9ea6d1e7fa10de9cbbc43e39d Signed-off-by: Karthik Anantha Ram Signed-off-by: Mukund Madhusudan Atre --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 50 +++++++++++++++++ .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 1 + .../isp_hw/top_tpg/cam_top_tpg103.h | 1 + .../isp_hw/top_tpg/cam_top_tpg_core.h | 2 + .../isp_hw/top_tpg/cam_top_tpg_ver3.c | 54 +++++++++++++++++-- .../isp_hw/top_tpg/cam_top_tpg_ver3.h | 1 + 6 files changed, 106 insertions(+), 3 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 99c25aa7d957..ab7adf18e91d 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -5370,6 +5370,37 @@ static int cam_isp_blob_clock_update( return rc; } +static int cam_isp_blob_tpg_config( + struct cam_isp_tpg_core_config *tpg_config, + struct cam_hw_prepare_update_args *prepare) +{ + int i, rc = -EINVAL; + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + + ctx = prepare->ctxt_to_hw_map; + hw_mgr_res = &ctx->res_list_tpg; + + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + CAM_DBG(CAM_ISP, "TPG ctrl config for hw %u", + hw_intf->hw_idx); + if (hw_intf->hw_ops.process_cmd) { + rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD, tpg_config, + sizeof(struct cam_isp_tpg_core_config)); + if (rc) + goto end; + } + } + +end: + return rc; +} + static int cam_isp_blob_sensor_config( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, @@ -6144,6 +6175,25 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, "Sensor Dimension Update Failed rc: %d", rc); } break; + case CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG: { + struct cam_isp_tpg_core_config *tpg_config; + + if (blob_size < sizeof(struct cam_isp_tpg_core_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %zu expected %zu", + blob_size, + sizeof(struct cam_isp_tpg_core_config)); + return -EINVAL; + } + + tpg_config = + (struct cam_isp_tpg_core_config *)blob_data; + + rc = cam_isp_blob_tpg_config(tpg_config, prepare); + if (rc) + CAM_ERR(CAM_ISP, + "TPG config failed rc: %d", rc); + } + break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index de5b0499603b..1935c5cd0d3c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -126,6 +126,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_GET_RES_FOR_MID, CAM_ISP_HW_CMD_BLANKING_UPDATE, CAM_ISP_HW_CMD_CSID_CLOCK_DUMP, + CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h index 396671852799..89880ae809bc 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h @@ -112,6 +112,7 @@ static struct cam_top_tpg_ver3_reg_offset cam_top_tpg103_reg = { .top_mux_reg_offset = 0x1C, .tpg_vc_dt_pattern_id_shift = 6, .tpg_num_active_vcs_shift = 30, + .tpg_color_bar_qcfa_en_shift = 3, }; struct cam_top_tpg_hw_info cam_top_tpg103_hw_info = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h index eb6e03a36cce..d904eb949817 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h @@ -80,6 +80,7 @@ struct cam_top_tpg_dt_cfg { * @vbi_cnt: vbi count * @num_active_dts: number of active dts need to configure * @num_frames: number of output frames + * @qcfa_en: enable qcfa in color bar cfg * @dt_cfg: dt configuration values * */ @@ -94,6 +95,7 @@ struct cam_top_tpg_cfg { uint32_t num_active_dts; uint32_t num_frames; uint32_t vc_dt_pattern_id; + uint32_t qcfa_en; struct cam_top_tpg_dt_cfg dt_cfg[4]; }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c index ee862e3db199..6955cf8729df 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c @@ -47,6 +47,52 @@ static int cam_top_tpg_ver3_get_hw_caps( return rc; } +static int cam_top_tpg_ver3_process_cmd(void *hw_priv, + uint32_t cmd_type, void *cmd_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_top_tpg_hw *tpg_hw; + struct cam_hw_info *tpg_hw_info; + struct cam_isp_tpg_core_config *core_cfg; + struct cam_top_tpg_cfg *tpg_data; + + if (!hw_priv || !cmd_args) { + CAM_ERR(CAM_ISP, "TPG: Invalid args"); + return -EINVAL; + } + + tpg_hw_info = (struct cam_hw_info *)hw_priv; + tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info; + tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv; + + switch (cmd_type) { + case CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD: + if (arg_size != sizeof(struct cam_isp_tpg_core_config)) { + CAM_ERR(CAM_ISP, "Invalid size %u expected %u", + arg_size, + sizeof(struct cam_isp_tpg_core_config)); + rc = -EINVAL; + break; + } + + core_cfg = (struct cam_isp_tpg_core_config *)cmd_args; + tpg_data->pix_pattern = core_cfg->pix_pattern; + tpg_data->vc_dt_pattern_id = core_cfg->vc_dt_pattern_id; + tpg_data->qcfa_en = core_cfg->qcfa_en; + CAM_DBG(CAM_ISP, + "pattern_id: 0x%x pix_pattern: 0x%x qcfa_en: 0x%x", + tpg_data->vc_dt_pattern_id, tpg_data->pix_pattern, + tpg_data->qcfa_en); + break; + default: + CAM_ERR(CAM_ISP, "Invalid TPG cmd type %u", cmd_type); + rc = -EINVAL; + break; + } + + return rc; +} + static int cam_top_tpg_ver3_reserve( void *hw_priv, void *reserve_args, @@ -95,7 +141,7 @@ static int cam_top_tpg_ver3_reserve( } tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv; - + memset(tpg_data, 0, sizeof(*tpg_data)); for (i = 0; i < reserv->in_port->num_valid_vc_dt; i++) { if (reserv->in_port->dt[i] > 0x3f || reserv->in_port->vc[i] > 0x1f) { @@ -218,6 +264,8 @@ static int cam_top_tpg_ver3_start( val = (1 << tpg_reg->tpg_split_en_shift); val |= tpg_data->pix_pattern; + if (tpg_data->qcfa_en) + val |= (1 << tpg_reg->tpg_color_bar_qcfa_en_shift); cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfg + 0x60 * i); @@ -236,7 +284,7 @@ static int cam_top_tpg_ver3_start( tpg_reg->tpg_vc0_hbi_cfg + 0x60 * i); if (tpg_data->v_blank_count) - cam_io_w_mb(tpg_data->h_blank_count, + cam_io_w_mb(tpg_data->v_blank_count, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_vbi_cfg + 0x60 * i); else @@ -340,6 +388,6 @@ int cam_top_tpg_ver3_init( tpg_hw->hw_intf->hw_ops.reserve = cam_top_tpg_ver3_reserve; tpg_hw->hw_intf->hw_ops.start = cam_top_tpg_ver3_start; tpg_hw->hw_intf->hw_ops.stop = cam_top_tpg_ver3_stop; - + tpg_hw->hw_intf->hw_ops.process_cmd = cam_top_tpg_ver3_process_cmd; return 0; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h index b8853d6215a2..401ba8127cd1 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h @@ -111,6 +111,7 @@ struct cam_top_tpg_ver3_reg_offset { uint32_t top_mux_reg_offset; uint32_t tpg_vc_dt_pattern_id_shift; uint32_t tpg_num_active_vcs_shift; + uint32_t tpg_color_bar_qcfa_en_shift; }; int cam_top_tpg_ver3_init(struct cam_top_tpg_hw *tpg_hw);