msm: camera: ife: Add support to provide IFE count in Query caps

IFE Query cap currently gives only IFE Full Information. Update the
code to return IFE Full, IFE lite, full IFE-CSID and IFE-CSID lite
information in return of the IFE Query cap command.

CRs-Fixed: 2647995
Change-Id: I84cf5b766ce191aacad4a1de478c6eebafe917b3
Signed-off-by: Jigar Agrawal <jigar@codeaurora.org>
This commit is contained in:
Jigar Agrawal
2020-06-08 14:15:12 -07:00
parent f65f27de96
commit 6de4fa2ed8
11 changed files with 225 additions and 34 deletions

View File

@@ -182,6 +182,11 @@ static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv,
struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv;
struct cam_query_cap_cmd *query = hw_caps_args;
struct cam_isp_query_cap_cmd query_isp;
struct cam_isp_dev_cap_info *ife_full_hw_info = NULL;
struct cam_isp_dev_cap_info *ife_lite_hw_info = NULL;
struct cam_isp_dev_cap_info *csid_full_hw_info = NULL;
struct cam_isp_dev_cap_info *csid_lite_hw_info = NULL;
struct cam_ife_csid_hw_caps *ife_csid_caps = {0};
CAM_DBG(CAM_ISP, "enter");
@@ -196,13 +201,98 @@ static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv,
query_isp.device_iommu.secure = hw_mgr->mgr_common.img_iommu_hdl_secure;
query_isp.cdm_iommu.non_secure = hw_mgr->mgr_common.cmd_iommu_hdl;
query_isp.cdm_iommu.secure = hw_mgr->mgr_common.cmd_iommu_hdl_secure;
query_isp.num_dev = 2;
for (i = 0; i < query_isp.num_dev; i++) {
query_isp.dev_caps[i].hw_type = CAM_ISP_HW_IFE;
query_isp.dev_caps[i].hw_version.major = 1;
query_isp.dev_caps[i].hw_version.minor = 7;
query_isp.dev_caps[i].hw_version.incr = 0;
query_isp.dev_caps[i].hw_version.reserved = 0;
query_isp.num_dev = 0;
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
if (!hw_mgr->ife_devices[i])
continue;
if (hw_mgr->ife_dev_caps[i].is_lite) {
if (ife_lite_hw_info == NULL) {
ife_lite_hw_info =
&query_isp.dev_caps[query_isp.num_dev];
query_isp.num_dev++;
ife_lite_hw_info->hw_type = CAM_ISP_HW_IFE_LITE;
ife_lite_hw_info->hw_version.major =
hw_mgr->ife_dev_caps[i].major;
ife_lite_hw_info->hw_version.minor =
hw_mgr->ife_dev_caps[i].minor;
ife_lite_hw_info->hw_version.incr =
hw_mgr->ife_dev_caps[i].incr;
ife_lite_hw_info->hw_version.reserved = 0;
ife_lite_hw_info->num_hw = 0;
}
ife_lite_hw_info->num_hw++;
} else {
if (ife_full_hw_info == NULL) {
ife_full_hw_info =
&query_isp.dev_caps[query_isp.num_dev];
query_isp.num_dev++;
ife_full_hw_info->hw_type = CAM_ISP_HW_IFE;
ife_full_hw_info->hw_version.major =
hw_mgr->ife_dev_caps[i].major;
ife_full_hw_info->hw_version.minor =
hw_mgr->ife_dev_caps[i].minor;
ife_full_hw_info->hw_version.incr =
hw_mgr->ife_dev_caps[i].incr;
ife_full_hw_info->hw_version.reserved = 0;
ife_full_hw_info->num_hw = 0;
}
ife_full_hw_info->num_hw++;
}
}
for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
if (!hw_mgr->csid_devices[i])
continue;
ife_csid_caps = (struct cam_ife_csid_hw_caps *)
&hw_mgr->ife_csid_dev_caps[i];
if (ife_csid_caps->is_lite) {
if (csid_lite_hw_info == NULL) {
csid_lite_hw_info =
&query_isp.dev_caps[query_isp.num_dev];
query_isp.num_dev++;
csid_lite_hw_info->hw_type =
CAM_ISP_HW_CSID_LITE;
csid_lite_hw_info->hw_version.major =
ife_csid_caps->major_version;
csid_lite_hw_info->hw_version.minor =
ife_csid_caps->minor_version;
csid_lite_hw_info->hw_version.incr =
ife_csid_caps->version_incr;
csid_lite_hw_info->hw_version.reserved = 0;
csid_lite_hw_info->num_hw = 0;
}
csid_lite_hw_info->num_hw++;
} else {
if (csid_full_hw_info == NULL) {
csid_full_hw_info =
&query_isp.dev_caps[query_isp.num_dev];
query_isp.num_dev++;
csid_full_hw_info->hw_type = CAM_ISP_HW_CSID;
csid_full_hw_info->hw_version.major =
ife_csid_caps->major_version;
csid_full_hw_info->hw_version.minor =
ife_csid_caps->minor_version;
csid_full_hw_info->hw_version.incr =
ife_csid_caps->version_incr;
csid_full_hw_info->hw_version.reserved = 0;
csid_full_hw_info->num_hw = 0;
}
csid_full_hw_info->num_hw++;
}
}
if (copy_to_user(u64_to_user_ptr(query->caps_handle),

View File

@@ -1223,7 +1223,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
int rc = 0;
const struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
uint32_t i, val;
uint32_t i;
int clk_lvl;
unsigned long flags;
@@ -1305,10 +1305,12 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_hw->csid_info->hw_reg_version =
cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_hw_version_addr);
CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
csid_hw->hw_intf->hw_idx, val);
csid_hw->hw_intf->hw_idx,
csid_hw->csid_info->hw_reg_version);
spin_lock_irqsave(&csid_hw->lock_state, flags);
csid_hw->device_enabled = 1;
@@ -3102,6 +3104,7 @@ int cam_ife_csid_get_hw_caps(void *hw_priv,
struct cam_ife_csid_hw *csid_hw;
struct cam_hw_info *csid_hw_info;
const struct cam_ife_csid_reg_offset *csid_reg;
struct cam_csid_soc_private *soc_priv = NULL;
if (!hw_priv || !get_hw_cap_args) {
CAM_ERR(CAM_ISP, "CSID: Invalid args");
@@ -3116,9 +3119,22 @@ int cam_ife_csid_get_hw_caps(void *hw_priv,
hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis;
hw_caps->num_pix = csid_reg->cmn_reg->num_pix;
hw_caps->num_ppp = csid_reg->cmn_reg->num_ppp;
hw_caps->major_version = csid_reg->cmn_reg->major_version;
hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
/* NOTE: HW version is not correct since we dont enable
* the soc resources in the probe for CSID, instead we
* when the camera actually runs
*/
hw_caps->version_incr =
csid_hw->csid_info->hw_reg_version & 0x00ffff;
hw_caps->minor_version =
(csid_hw->csid_info->hw_reg_version >> 16) & 0x0fff;
hw_caps->major_version =
(csid_hw->csid_info->hw_reg_version >> 28) & 0x000f;
soc_priv = (struct cam_csid_soc_private *)
(csid_hw_info->soc_info.soc_private);
hw_caps->is_lite = soc_priv->is_ife_csid_lite;
CAM_DBG(CAM_ISP,
"CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",

View File

@@ -402,12 +402,14 @@ struct cam_ife_csid_reg_offset {
*
* @csid_reg: csid register offsets
* @hw_dts_version: HW DTS version
* @hw_reg_version: HW Version read from register
* @csid_max_clk: maximim csid clock
*
*/
struct cam_ife_csid_hw_info {
const struct cam_ife_csid_reg_offset *csid_reg;
uint32_t hw_dts_version;
uint32_t hw_reg_version;
uint32_t csid_max_clk;
};

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include "cam_ife_csid_soc.h"
@@ -10,16 +10,23 @@
static int cam_ife_csid_get_dt_properties(struct cam_hw_soc_info *soc_info)
{
struct device_node *of_node = NULL;
struct csid_device_soc_info *csid_soc_info = NULL;
struct cam_csid_soc_private *soc_private = NULL;
int rc = 0;
of_node = soc_info->pdev->dev.of_node;
csid_soc_info = (struct csid_device_soc_info *)soc_info->soc_private;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc)
return rc;
soc_private = (struct cam_csid_soc_private *)soc_info->soc_private;
soc_private->is_ife_csid_lite = false;
if (strnstr(soc_info->compatible, "lite",
strlen(soc_info->compatible)) != NULL) {
soc_private->is_ife_csid_lite = true;
}
return rc;
}

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_IFE_CSID_SOC_H_
@@ -16,9 +16,11 @@
* @cpas_handle: Handle returned on registering with CPAS driver.
* This handle is used for all further interface
* with CPAS.
* @is_ife_csid_lite: Flag to indicate Whether a full csid or a Lite csid
*/
struct cam_csid_soc_private {
uint32_t cpas_handle;
bool is_ife_csid_lite;
};
/**

View File

@@ -49,7 +49,7 @@ enum cam_ife_cid_res_id {
* @major_version : major version
* @minor_version: minor version
* @version_incr: version increment
*
* @is_lite: is the ife_csid lite
*/
struct cam_ife_csid_hw_caps {
uint32_t num_rdis;
@@ -58,6 +58,7 @@ struct cam_ife_csid_hw_caps {
uint32_t major_version;
uint32_t minor_version;
uint32_t version_incr;
bool is_lite;
};
struct cam_isp_out_port_generic_info {

View File

@@ -90,16 +90,17 @@ enum cam_vfe_reset_type {
/*
* struct cam_vfe_hw_get_hw_cap:
*
* @max_width: Max width supported by HW
* @max_height: Max height supported by HW
* @max_pixel_num: Max Pixel channels available
* @max_rdi_num: Max Raw channels available
* @Brief: Argument type for fetching the hw information for Query caps
* @major: Major revision number
* @minor: Minor revision number
* @incr: Increment revision number
* @is_lite: Flag to indicate Whether a full vfe or a Lite vfe
*/
struct cam_vfe_hw_get_hw_cap {
uint32_t max_width;
uint32_t max_height;
uint32_t max_pixel_num;
uint32_t max_rdi_num;
uint32_t major;
uint32_t minor;
uint32_t incr;
bool is_lite;
};
/*

View File

@@ -27,6 +27,7 @@ struct cam_vfe_top_priv_common {
CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES];
uint32_t last_counter;
uint64_t total_bw_applied;
uint32_t hw_version;
enum cam_vfe_bw_control_action axi_vote_control[CAM_VFE_TOP_MUX_MAX];
};

View File

@@ -282,9 +282,39 @@ static int cam_vfe_top_get_data(
}
int cam_vfe_top_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size)
void *args, uint32_t arg_size)
{
return -EPERM;
struct cam_vfe_hw_get_hw_cap *vfe_cap_info = NULL;
struct cam_vfe_top_ver2_priv *vfe_top_prv = NULL;
struct cam_vfe_soc_private *vfe_soc_private = NULL;
if (!device_priv || !args) {
CAM_ERR(CAM_ISP,
"Invalid arguments device_priv:%p, args:%p",
device_priv, args);
return -EINVAL;
}
vfe_cap_info = (struct cam_vfe_hw_get_hw_cap *)args;
vfe_top_prv = (struct cam_vfe_top_ver2_priv *)device_priv;
if (!vfe_top_prv->common_data.soc_info) {
CAM_ERR(CAM_ISP, "soc_info is null");
return -EFAULT;
}
vfe_soc_private = (struct cam_vfe_soc_private *)
vfe_top_prv->common_data.soc_info->soc_private;
vfe_cap_info->is_lite = (vfe_soc_private->is_ife_lite) ? true : false;
vfe_cap_info->incr =
(vfe_top_prv->top_common.hw_version) & 0x00ffff;
vfe_cap_info->minor =
((vfe_top_prv->top_common.hw_version) >> 16) & 0x0fff;
vfe_cap_info->major =
((vfe_top_prv->top_common.hw_version) >> 28) & 0x000f;
return 0;
}
static int cam_vfe_hw_dump(
@@ -425,9 +455,14 @@ int cam_vfe_top_init_hw(void *device_priv,
void *init_hw_args, uint32_t arg_size)
{
struct cam_vfe_top_ver2_priv *top_priv = device_priv;
struct cam_vfe_top_ver2_common_data common_data = top_priv->common_data;
top_priv->hw_clk_rate = 0;
top_priv->top_common.hw_version =
cam_io_r_mb(common_data.soc_info->reg_map[0].mem_base +
common_data.common_reg->hw_version);
return 0;
}

View File

@@ -323,9 +323,39 @@ static int cam_vfe_top_ver3_get_data(
}
int cam_vfe_top_ver3_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size)
void *args, uint32_t arg_size)
{
return -EPERM;
struct cam_vfe_hw_get_hw_cap *vfe_cap_info = NULL;
struct cam_vfe_top_ver3_priv *vfe_top_prv = NULL;
struct cam_vfe_soc_private *vfe_soc_private = NULL;
if (!device_priv || !args) {
CAM_ERR(CAM_ISP,
"Invalid arguments device_priv:%p, args:%p",
device_priv, args);
return -EINVAL;
}
vfe_cap_info = (struct cam_vfe_hw_get_hw_cap *)args;
vfe_top_prv = (struct cam_vfe_top_ver3_priv *)device_priv;
if (!vfe_top_prv->common_data.soc_info) {
CAM_ERR(CAM_ISP, "soc_info is null");
return -EFAULT;
}
vfe_soc_private = (struct cam_vfe_soc_private *)
vfe_top_prv->common_data.soc_info->soc_private;
vfe_cap_info->is_lite = (vfe_soc_private->is_ife_lite) ? true : false;
vfe_cap_info->incr =
(vfe_top_prv->top_common.hw_version) & 0x00ffff;
vfe_cap_info->minor =
((vfe_top_prv->top_common.hw_version) >> 16) & 0x0fff;
vfe_cap_info->major =
((vfe_top_prv->top_common.hw_version) >> 28) & 0x000f;
return 0;
}
int cam_vfe_top_ver3_init_hw(void *device_priv,
@@ -354,6 +384,10 @@ int cam_vfe_top_ver3_init_hw(void *device_priv,
cam_soc_util_w_mb(common_data.soc_info, VFE_CORE_BASE_IDX,
common_data.common_reg->noc_cgc_ovd, 0x0);
top_priv->top_common.hw_version =
cam_io_r_mb(common_data.soc_info->reg_map[0].mem_base +
common_data.common_reg->hw_version);
return 0;
}

View File

@@ -20,7 +20,9 @@
#define CAM_ISP_HW_VFE 2
#define CAM_ISP_HW_IFE 3
#define CAM_ISP_HW_ISPIF 4
#define CAM_ISP_HW_MAX 5
#define CAM_ISP_HW_IFE_LITE 5
#define CAM_ISP_HW_CSID_LITE 6
#define CAM_ISP_HW_MAX 7
/* Color Pattern */
#define CAM_ISP_PATTERN_BAYER_RGRGRG 0
@@ -140,13 +142,13 @@
* struct cam_isp_dev_cap_info - A cap info for particular hw type
*
* @hw_type: Hardware type for the cap info
* @reserved: reserved field for alignment
* @num_hw: Number of HW of type @hw_type
* @hw_version: Hardware version
*
*/
struct cam_isp_dev_cap_info {
__u32 hw_type;
__u32 reserved;
__u32 hw_type;
__u32 num_hw;
struct cam_hw_version hw_version;
};