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 bfdc76f930d8..0abb6f8653f1 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 @@ -36,7 +36,7 @@ (CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON + 1) #define CAM_ISP_GENERIC_BLOB_TYPE_MAX \ - (CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 + 1) + (CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG + 1) static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_GET_HFR_UPDATE, @@ -5440,6 +5440,76 @@ static int cam_isp_blob_clock_update( return rc; } +static int cam_isp_blob_sensor_config( + uint32_t blob_type, + struct cam_isp_generic_blob_info *blob_info, + struct cam_isp_sensor_config *dim_config, + struct cam_isp_hw_update_args *prepare) +{ + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_ife_sensor_dimension_update_args update_args; + int rc = -EINVAL, found = 0; + uint32_t i, j; + struct cam_isp_sensor_dimension *path_config; + + ctx = prepare->ctxt_to_hw_map; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + found = 1; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf && hw_intf->hw_ops.process_cmd) { + path_config = &(dim_config->ipp_path); + update_args.ipp_path.width = + path_config->width; + update_args.ipp_path.height = + path_config->height; + update_args.ipp_path.measure_enabled = + path_config->measure_enabled; + path_config = &(dim_config->ppp_path); + update_args.ppp_path.width = + path_config->width; + update_args.ppp_path.height = + path_config->height; + update_args.ppp_path.measure_enabled = + path_config->measure_enabled; + for (j = 0; j < CAM_IFE_RDI_NUM_MAX; j++) { + path_config = + &(dim_config->rdi_path[j]); + update_args.rdi_path[j].width = + path_config->width; + update_args.rdi_path[j].height = + path_config->height; + update_args.rdi_path[j].measure_enabled = + path_config->measure_enabled; + } + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, + &update_args, + sizeof( + struct + cam_ife_sensor_dimension_update_args) + ); + if (rc) { + CAM_ERR(CAM_ISP, + "Dimension Update failed"); + break; + } + } else + CAM_ERR(CAM_ISP, "hw_intf is NULL"); + } + if (found) + break; + } + + return rc; +} + static int cam_isp_blob_vfe_out_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, @@ -6064,6 +6134,26 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "CSID Config failed rc: %d", rc); } break; + case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG: { + struct cam_isp_sensor_config *csid_dim_config; + + if (blob_size < sizeof(struct cam_isp_sensor_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %zu expected %zu", + blob_size, + sizeof(struct cam_isp_sensor_config)); + return -EINVAL; + } + + csid_dim_config = + (struct cam_isp_sensor_config *)blob_data; + + rc = cam_isp_blob_sensor_config(blob_type, blob_info, + csid_dim_config, prepare); + if (rc) + CAM_ERR(CAM_ISP, + "Sensor Dimension Update 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/ife_csid_hw/cam_ife_csid170.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h index 714fa8ef2b31..bc564b2e1f77 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_170_H_ @@ -286,6 +286,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0x0, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h index 47cb02492412..f7608a73fad6 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h @@ -349,6 +349,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0xFFFF, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_170_200_reg_offset = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h index 70f96ea416d8..734218bf5144 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_175_H_ @@ -327,6 +327,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0xFFFF, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_175_reg_offset = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h index 612379ec4bdd..1794a860b84e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_175_200_H_ @@ -345,6 +345,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0xFFFF, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_175_200_reg_offset = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h index 66c1b32d51b0..316c3e2ab629 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_480_H_ @@ -365,6 +365,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0xFFFF, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_480_reg_offset = { 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 66803e43100d..ec7b77238ce4 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 @@ -82,7 +82,7 @@ static int cam_ife_csid_is_ipp_ppp_format_supported( static int cam_ife_csid_get_format_rdi( uint32_t in_format, uint32_t out_format, uint32_t *decode_fmt, - uint32_t *plain_fmt, uint32_t *packing_fmt, bool rpp) + uint32_t *plain_fmt, uint32_t *packing_fmt, bool rpp, uint32_t *in_bpp) { int rc = 0; @@ -104,6 +104,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 6; break; case CAM_FORMAT_MIPI_RAW_8: switch (out_format) { @@ -123,6 +124,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 8; break; case CAM_FORMAT_MIPI_RAW_10: switch (out_format) { @@ -142,6 +144,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 10; break; case CAM_FORMAT_MIPI_RAW_12: switch (out_format) { @@ -160,6 +163,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 12; break; case CAM_FORMAT_MIPI_RAW_14: switch (out_format) { @@ -178,6 +182,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 14; break; case CAM_FORMAT_MIPI_RAW_16: switch (out_format) { @@ -196,6 +201,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 16; break; case CAM_FORMAT_MIPI_RAW_20: switch (out_format) { @@ -214,6 +220,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 20; break; case CAM_FORMAT_DPCM_10_6_10: *decode_fmt = 0x7; @@ -1327,6 +1334,7 @@ err: static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) { int rc = -EINVAL; + uint32_t i; struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_reg_offset *csid_reg; unsigned long flags; @@ -1367,6 +1375,12 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) spin_lock_irqsave(&csid_hw->lock_state, flags); csid_hw->device_enabled = 0; spin_unlock_irqrestore(&csid_hw->lock_state, flags); + + csid_hw->ipp_path_config.measure_enabled = 0; + csid_hw->ppp_path_config.measure_enabled = 0; + for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) + csid_hw->rdi_path_config[i].measure_enabled = 0; + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; csid_hw->prev_boot_timestamp = 0; @@ -1720,6 +1734,7 @@ static int cam_ife_csid_init_config_pxl_path( bool is_ipp; uint32_t decode_format = 0, plain_format = 0, val = 0; uint32_t camera_hw_version; + struct cam_isp_sensor_dimension *path_config; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -1728,9 +1743,11 @@ static int cam_ife_csid_init_config_pxl_path( if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { is_ipp = true; pxl_reg = csid_reg->ipp_reg; + path_config = &(csid_hw->ipp_path_config); } else { is_ipp = false; pxl_reg = csid_reg->ppp_reg; + path_config = &(csid_hw->ppp_path_config); } if (!pxl_reg) { @@ -1846,6 +1863,25 @@ static int cam_ife_csid_init_config_pxl_path( pxl_reg->csid_pxl_irq_subsample_period_addr); cam_io_w_mb(0, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_irq_subsample_pattern_addr); + + /* configure pixel format measure */ + if (path_config->measure_enabled) { + val = (((path_config->height & + csid_reg->cmn_reg->format_measure_height_mask_val) << + csid_reg->cmn_reg->format_measure_height_shift_val) | + (path_config->width & + csid_reg->cmn_reg->format_measure_width_mask_val)); + CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x", + csid_hw->hw_intf->hw_idx, val); + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_format_measure_cfg1_addr); + + /* enable pixel and line counter */ + cam_io_w_mb(3, soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_format_measure_cfg0_addr); + } + /* set pxl drop pattern to 0 and period to 1 */ cam_io_w_mb(0, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_pix_drop_pattern_addr); @@ -1995,6 +2031,7 @@ static int cam_ife_csid_enable_pxl_path( const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; bool is_ipp; uint32_t val = 0; + struct cam_isp_sensor_dimension *path_config; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -2003,9 +2040,11 @@ static int cam_ife_csid_enable_pxl_path( if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { is_ipp = true; pxl_reg = csid_reg->ipp_reg; + path_config = &(csid_hw->ipp_path_config); } else { is_ipp = false; pxl_reg = csid_reg->ppp_reg; + path_config = &(csid_hw->ppp_path_config); } if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { @@ -2074,6 +2113,10 @@ static int cam_ife_csid_enable_pxl_path( if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; + if (path_config->measure_enabled) + val |= (CSID_PATH_ERROR_PIX_COUNT | + CSID_PATH_ERROR_LINE_COUNT); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_irq_mask_addr); @@ -2187,7 +2230,8 @@ static int cam_ife_csid_init_config_rdi_path( const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; uint32_t path_format = 0, plain_fmt = 0, val = 0, id; - uint32_t format_measure_addr, camera_hw_version, packing_fmt = 0; + uint32_t format_measure_addr, camera_hw_version; + uint32_t packing_fmt = 0, in_bpp = 0; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -2202,7 +2246,7 @@ static int cam_ife_csid_init_config_rdi_path( rc = cam_ife_csid_get_format_rdi(path_data->in_format, path_data->out_format, &path_format, &plain_fmt, &packing_fmt, - path_data->crop_enable || path_data->drop_enable); + path_data->crop_enable || path_data->drop_enable, &in_bpp); if (rc) return rc; @@ -2284,6 +2328,35 @@ static int cam_ife_csid_init_config_rdi_path( csid_reg->rdi_reg[id]->csid_rdi_err_recovery_cfg0_addr); } + /* configure pixel format measure */ + if (csid_hw->rdi_path_config[id].measure_enabled) { + val = ((csid_hw->rdi_path_config[id].height & + csid_reg->cmn_reg->format_measure_height_mask_val) << + csid_reg->cmn_reg->format_measure_height_shift_val); + + if (path_format == 0xF) + val |= (__KERNEL_DIV_ROUND_UP( + (csid_hw->rdi_path_config[id].width * + in_bpp), 8) & + csid_reg->cmn_reg->format_measure_width_mask_val); + else + val |= (csid_hw->rdi_path_config[id].width & + csid_reg->cmn_reg->format_measure_width_mask_val); + + CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x", + csid_hw->hw_intf->hw_idx, val); + CAM_DBG(CAM_ISP, "format measure width : 0x%x height : 0x%x", + csid_hw->rdi_path_config[id].width, + csid_hw->rdi_path_config[id].height); + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr); + + /* enable pixel and line counter */ + cam_io_w_mb(3, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr); + } + /* set frame drop pattern to 0 and period to 1 */ cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr); @@ -2381,7 +2454,7 @@ static int cam_ife_csid_init_config_udi_path( const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; uint32_t path_format = 0, plain_fmt = 0, val = 0, val1, id; - uint32_t format_measure_addr, packing_fmt = 0; + uint32_t format_measure_addr, packing_fmt = 0, in_bpp = 0; path_data = (struct cam_ife_csid_path_cfg *)res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -2396,7 +2469,7 @@ static int cam_ife_csid_init_config_udi_path( rc = cam_ife_csid_get_format_rdi(path_data->in_format, path_data->out_format, &path_format, &plain_fmt, &packing_fmt, - path_data->crop_enable || path_data->drop_enable); + path_data->crop_enable || path_data->drop_enable, &in_bpp); if (rc) { CAM_ERR(CAM_ISP, "Failed to get format in_format: %u out_format: %u rc: %d", @@ -2660,9 +2733,14 @@ static int cam_ife_csid_enable_rdi_path( if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) val |= CSID_PATH_INFO_INPUT_SOF; + if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; + if (csid_hw->rdi_path_config[id].measure_enabled) + val |= (CSID_PATH_ERROR_PIX_COUNT | + CSID_PATH_ERROR_LINE_COUNT); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); @@ -3272,6 +3350,13 @@ int cam_ife_csid_release(void *hw_priv, break; case CAM_ISP_RESOURCE_PIX_PATH: res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + csid_hw->ipp_path_config.measure_enabled = 0; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + csid_hw->ppp_path_config.measure_enabled = 0; + else + csid_hw->rdi_path_config[res->res_id].measure_enabled + = 0; break; default: CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", @@ -3819,6 +3904,58 @@ static int cam_ife_csid_set_csid_clock( return 0; } +static int cam_ife_csid_set_sensor_dimension( + struct cam_ife_csid_hw *csid_hw, void *cmd_args) +{ + struct cam_ife_sensor_dimension_update_args *dimension_update = NULL; + uint32_t i; + + if (!csid_hw) + return -EINVAL; + + dimension_update = + (struct cam_ife_sensor_dimension_update_args *)cmd_args; + csid_hw->ipp_path_config.measure_enabled = + dimension_update->ipp_path.measure_enabled; + if (dimension_update->ipp_path.measure_enabled) { + csid_hw->ipp_path_config.width = + dimension_update->ipp_path.width; + csid_hw->ipp_path_config.height = + dimension_update->ipp_path.height; + CAM_DBG(CAM_ISP, "CSID ipp path width %d height %d", + csid_hw->ipp_path_config.width, + csid_hw->ipp_path_config.height); + } + csid_hw->ppp_path_config.measure_enabled = + dimension_update->ppp_path.measure_enabled; + if (dimension_update->ppp_path.measure_enabled) { + csid_hw->ppp_path_config.width = + dimension_update->ppp_path.width; + csid_hw->ppp_path_config.height = + dimension_update->ppp_path.height; + CAM_DBG(CAM_ISP, "CSID ppp path width %d height %d", + csid_hw->ppp_path_config.width, + csid_hw->ppp_path_config.height); + } + for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) { + csid_hw->rdi_path_config[i].measure_enabled + = dimension_update->rdi_path[i].measure_enabled; + if (csid_hw->rdi_path_config[i].measure_enabled) { + csid_hw->rdi_path_config[i].width = + dimension_update->rdi_path[i].width; + csid_hw->rdi_path_config[i].height = + dimension_update->rdi_path[i].height; + if (csid_hw->rdi_path_config[i].height == 1) + csid_hw->rdi_path_config[i].measure_enabled = 0; + CAM_DBG(CAM_ISP, + "CSID rdi path[%d] width %d height %d", + i, csid_hw->rdi_path_config[i].width, + csid_hw->rdi_path_config[i].height); + } + } + return 0; +} + static int cam_ife_csid_set_csid_qcfa( struct cam_ife_csid_hw *csid_hw, void *cmd_args) { @@ -3959,6 +4096,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_DUMP_HW: rc = cam_ife_csid_dump_hw(csid_hw, cmd_args); break; + case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: + rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); @@ -3979,7 +4119,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0; uint32_t irq_status_rdi[CAM_IFE_CSID_RDI_MAX] = {0, 0, 0, 0}; uint32_t irq_status_udi[CAM_IFE_CSID_UDI_MAX] = {0, 0, 0}; - uint32_t val, irq_status_ppp = 0; + uint32_t val, val2, irq_status_ppp = 0; bool fatal_err_detected = false; uint32_t sof_irq_debug_en = 0; unsigned long flags; @@ -4306,6 +4446,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) soc_info->reg_map[0].mem_base + csid_reg->ipp_reg->csid_pxl_ctrl_addr); } + + if ((irq_status_ipp & CSID_PATH_ERROR_PIX_COUNT) || + (irq_status_ipp & CSID_PATH_ERROR_LINE_COUNT)) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->csid_pxl_format_measure0_addr); + + CAM_ERR(CAM_ISP, + "CSID:%d irq_status_ipp:0x%x", + csid_hw->hw_intf->hw_idx, irq_status_ipp); + CAM_ERR(CAM_ISP, + "Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x", + csid_hw->ipp_path_config.height, + csid_hw->ipp_path_config.width, + ((val >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val & + csid_reg->cmn_reg->format_measure_width_mask_val); + } } /*read PPP errors */ @@ -4349,6 +4508,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) soc_info->reg_map[0].mem_base + csid_reg->ppp_reg->csid_pxl_ctrl_addr); } + + if ((irq_status_ppp & CSID_PATH_ERROR_PIX_COUNT) || + (irq_status_ppp & CSID_PATH_ERROR_LINE_COUNT)) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->csid_pxl_format_measure0_addr); + + CAM_ERR(CAM_ISP, + "CSID:%d irq_status_ppp:0x%x", + csid_hw->hw_intf->hw_idx, irq_status_ppp); + CAM_ERR(CAM_ISP, + "Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x", + csid_hw->ppp_path_config.height, + csid_hw->ppp_path_config.width, + ((val >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val & + csid_reg->cmn_reg->format_measure_width_mask_val); + } } for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { @@ -4389,6 +4567,30 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr); } + + if ((irq_status_rdi[i] & CSID_PATH_ERROR_PIX_COUNT) || + (irq_status_rdi[i] & CSID_PATH_ERROR_LINE_COUNT)) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->csid_rdi_format_measure0_addr); + val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->csid_rdi_format_measure_cfg1_addr + ); + CAM_ERR(CAM_ISP, + "CSID:%d irq_status_rdi[%d]:0x%x", + csid_hw->hw_intf->hw_idx, i, irq_status_rdi[i]); + CAM_ERR(CAM_ISP, + "Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x", + ((val2 >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val2 & + csid_reg->cmn_reg->format_measure_width_mask_val, + ((val >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val & + csid_reg->cmn_reg->format_measure_width_mask_val); + } } for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { @@ -4602,6 +4804,10 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, ife_csid_hw->csid_debug = 0; ife_csid_hw->error_irq_count = 0; + ife_csid_hw->ipp_path_config.measure_enabled = 0; + ife_csid_hw->ppp_path_config.measure_enabled = 0; + for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) + ife_csid_hw->rdi_path_config[i].measure_enabled = 0; return 0; err: diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index f75b97224e60..a3f34947a253 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -373,6 +373,10 @@ struct cam_ife_csid_common_reg_offset { uint32_t measure_en_hbi_vbi_cnt_mask; uint32_t format_measure_en_val; uint32_t num_bytes_out_shift_val; + uint32_t format_measure_width_shift_val; + uint32_t format_measure_width_mask_val; + uint32_t format_measure_height_shift_val; + uint32_t format_measure_height_mask_val; }; /** @@ -580,6 +584,11 @@ struct cam_ife_csid_hw { struct completion csid_udin_complete[CAM_IFE_CSID_UDI_MAX]; uint64_t csid_debug; uint64_t clk_rate; + struct cam_isp_sensor_dimension ipp_path_config; + struct cam_isp_sensor_dimension ppp_path_config; + struct cam_isp_sensor_dimension rdi_path_config[CAM_IFE_CSID_RDI_MAX]; + uint32_t hbi; + uint32_t vbi; bool sof_irq_triggered; bool is_resetting; uint32_t irq_debug_cnt; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 78c457b6a7cb..1998f19b7918 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -206,6 +206,7 @@ enum cam_ife_csid_cmd_type { CAM_IFE_CSID_SET_CSID_DEBUG, CAM_IFE_CSID_SOF_IRQ_DEBUG, CAM_IFE_CSID_SET_CONFIG, + CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, CAM_IFE_CSID_CMD_MAX, }; @@ -247,4 +248,17 @@ struct cam_ife_csid_epd_update_args { uint32_t epd_supported; }; +/* + * struct cam_ife_sensor_dim_update_args: + * + * @ppp_path: expected ppp path configuration + * @ipp_path: expected ipp path configuration + * @rdi_path: expected rdi path configuration + */ +struct cam_ife_sensor_dimension_update_args { + struct cam_isp_sensor_dimension ppp_path; + struct cam_isp_sensor_dimension ipp_path; + struct cam_isp_sensor_dimension rdi_path[CAM_IFE_CSID_RDI_MAX]; +}; + #endif /* _CAM_CSID_HW_INTF_H_ */ diff --git a/include/uapi/camera/media/cam_isp.h b/include/uapi/camera/media/cam_isp.h index c3126dac8eee..ce9bdde64210 100644 --- a/include/uapi/camera/media/cam_isp.h +++ b/include/uapi/camera/media/cam_isp.h @@ -92,18 +92,19 @@ #define CAM_ISP_DSP_MODE_ROUND 2 /* ISP Generic Cmd Buffer Blob types */ -#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG 0 -#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1 -#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG 2 -#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG 3 -#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4 -#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 -#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2 6 -#define CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG 7 -#define CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG 8 -#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 9 -#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CONFIG 10 -#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG 12 +#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG 0 +#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1 +#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG 2 +#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG 3 +#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4 +#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 +#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2 6 +#define CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG 7 +#define CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG 8 +#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 9 +#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CONFIG 10 +#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG 11 +#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG 12 #define CAM_ISP_VC_DT_CFG 4 @@ -135,6 +136,8 @@ #define CAM_ISP_ACQ_CUSTOM_PRIMARY 1 #define CAM_ISP_ACQ_CUSTOM_SECONDARY 2 +#define CAM_IFE_CSID_RDI_MAX 4 + /* Query devices */ /** * struct cam_isp_dev_cap_info - A cap info for particular hw type @@ -597,6 +600,37 @@ struct cam_fe_config { __u32 latency_buf_size; } __attribute__((packed)); + +/** + * struct cam_isp_sensor_path_dimension + * + * @width expected width + * @height expected height + * @measure_enabled flag to indicate if pixel measurement is to be enabled + */ +struct cam_isp_sensor_dimension { + __u32 width; + __u32 height; + __u32 measure_enabled; +} __attribute__((packed)); + +/** + * struct cam_isp_sensor_config - Sensor Dimension configuration + * + * @ppp_path: expected ppp path configuration + * @ipp_path: expected ipp path configuration + * @rdi_path: expected rdi path configuration + * @hbi: HBI value + * @vbi: VBI value + */ +struct cam_isp_sensor_config { + struct cam_isp_sensor_dimension ppp_path; + struct cam_isp_sensor_dimension ipp_path; + struct cam_isp_sensor_dimension rdi_path[CAM_IFE_CSID_RDI_MAX]; + __u32 hbi; + __u32 vbi; +} __attribute__((packed)); + /** * struct cam_isp_core_config - ISP core registers configuration *