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 <kartanan@codeaurora.org>
Signed-off-by: Mukund Madhusudan Atre <matre@codeaurora.org>
This commit is contained in:
Karthik Anantha Ram 2020-08-07 15:00:29 -07:00
commit d2461de353
6 changed files with 106 additions and 3 deletions

View file

@ -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;

View file

@ -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,
};

View file

@ -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 = {

View file

@ -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];
};

View file

@ -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;
}

View file

@ -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);