Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a3f5094 authored by Ravikishore Pampana's avatar Ravikishore Pampana
Browse files

msm: camera: tfe: Do tfe-csid and tfe probe based on fuse feature



Some ISP hardware id instances are disabled on some target skus.
Cpas driver has fuse information based on the dtsi entries.
ISP hw driver queries the cpas driver whether hw instance is
supported or not. If ISP hardware is supported on the target then
continue the isp hardware probe.

CRs-Fixed: 2670876
Change-Id: I6b2316d87aeabccbdf74e151e0e25ff77ed6634f
Signed-off-by: default avatarRavikishore Pampana <rpampana@codeaurora.org>
parent 1ed6c5c6
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
// 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/of.h>
@@ -118,28 +118,37 @@ const char *cam_cpas_axi_util_trans_type_to_string(
}
EXPORT_SYMBOL(cam_cpas_axi_util_trans_type_to_string);

int cam_cpas_is_feature_supported(uint32_t flag)
bool cam_cpas_is_feature_supported(uint32_t flag,
	uint32_t hw_id)
{
	struct cam_hw_info *cpas_hw = NULL;
	struct cam_cpas_private_soc *soc_private = NULL;
	uint32_t feature_mask;
	uint32_t i;
	bool  supported = true;

	if (!CAM_CPAS_INTF_INITIALIZED()) {
		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
		return -ENODEV;
		return false;
	}

	cpas_hw = (struct cam_hw_info *) g_cpas_intf->hw_intf->hw_priv;
	soc_private =
		(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
	feature_mask = soc_private->feature_mask;

	if (flag >= CAM_CPAS_FUSE_FEATURE_MAX) {
		CAM_ERR(CAM_CPAS, "Unknown feature flag %x", flag);
		return -EINVAL;
		return false;
	}

	for (i = 0; i < soc_private->num_feature_entries; i++) {
		if ((soc_private->feature_info[i].feature == flag) &&
			(soc_private->feature_info[i].hw_id == hw_id)) {
			supported = soc_private->feature_info[i].enable;
			break;
		}
	}

	return feature_mask & flag ? 1 : 0;
	return supported;
}
EXPORT_SYMBOL(cam_cpas_is_feature_supported);

+66 −14
Original line number Diff line number Diff line
@@ -401,42 +401,95 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
	return 0;
}


int cam_cpas_get_hw_features(struct platform_device *pdev,
	struct cam_cpas_private_soc *soc_private)
{
	struct device_node *of_node;
	void *fuse;
	uint32_t fuse_addr, fuse_bit;
	uint32_t fuse_val = 0, feature_bit_pos;
	int count = 0, i = 0;
	uint32_t fuse_val = 0, feature;
	uint32_t enable_type = 0, hw_id = 0;
	int count = 0, i = 0, num_feature = 0;

	of_node = pdev->dev.of_node;
	count = of_property_count_u32_elems(of_node, "cam_hw_fuse");

	for (i = 0; (i + 3) <= count; i = i + 3) {
	CAM_DBG(CAM_CPAS, "fuse info elements count %d", count);

	if (count <= 0)
		goto end;

	for (i = 0; (i + 5) <= count; i = i + 5) {
		of_property_read_u32_index(of_node, "cam_hw_fuse", i,
				&feature_bit_pos);
				&feature);
		of_property_read_u32_index(of_node, "cam_hw_fuse", i + 1,
				&fuse_addr);
		of_property_read_u32_index(of_node, "cam_hw_fuse", i + 2,
				&fuse_bit);
		CAM_INFO(CAM_CPAS, "feature_bit 0x%x addr 0x%x, bit %d",
				feature_bit_pos, fuse_addr, fuse_bit);
		of_property_read_u32_index(of_node, "cam_hw_fuse", i + 3,
				&enable_type);
		of_property_read_u32_index(of_node, "cam_hw_fuse", i + 4,
				&hw_id);
		CAM_INFO(CAM_CPAS,
			"feature 0x%x addr 0x%x, bit %d enable type:%d hw_id=%d",
				feature, fuse_addr, fuse_bit,
				enable_type, hw_id);

		fuse = ioremap(fuse_addr, 4);
		if (fuse) {
			fuse_val = cam_io_r(fuse);
			if (fuse_val & BIT(fuse_bit))
				soc_private->feature_mask |= feature_bit_pos;
		} else {
			/* if fuse ioremap is failed, disable the feature */
			CAM_ERR(CAM_CPAS,
				"fuse register io remap failed fuse_addr:0x%x feature0x%x ",
				fuse_addr, feature);

			if (enable_type)
				fuse_val = ~BIT(fuse_bit);
			else
				soc_private->feature_mask &= ~feature_bit_pos;
				fuse_val = BIT(fuse_bit);
		}
		CAM_INFO(CAM_CPAS, "fuse %pK, fuse_val %x, feature_mask %x",
				fuse, fuse_val, soc_private->feature_mask);

		soc_private->feature_info[num_feature].feature =
			feature;
		soc_private->feature_info[num_feature].hw_id = hw_id;

		if (enable_type) {
		/*
		 * fuse is for enable feature
		 * if fust bit is set means feature is enabled or
		 * HW is enabled
		 */
			if (fuse_val & BIT(fuse_bit))
				soc_private->feature_info[num_feature].enable =
				true;
			else
				soc_private->feature_info[num_feature].enable =
				false;
		} else {
		/*
		 * fuse is for disable feature
		 * if fust bit is set means feature is disabled or
		 * HW is disabled
		 */
			if (fuse_val & BIT(fuse_bit))
				soc_private->feature_info[num_feature].enable =
				false;
			else
				soc_private->feature_info[num_feature].enable =
				true;
		}
		CAM_INFO(CAM_CPAS,
			"num entries:%d feature 0x%x enable=%d hw id=%d",
				num_feature,
				soc_private->feature_info[num_feature].feature,
				soc_private->feature_info[num_feature].enable,
				soc_private->feature_info[num_feature].hw_id);
		num_feature++;
	}

end:
	soc_private->num_feature_entries = num_feature;
	return 0;
}

@@ -454,8 +507,7 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
	}

	of_node = pdev->dev.of_node;
	soc_private->feature_mask = 0xFFFFFFFF;

	soc_private->num_feature_entries = 0;
	rc = of_property_read_string(of_node, "arch-compat",
		&soc_private->arch_compat);
	if (rc) {
+20 −3
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@

#define CAM_REGULATOR_LEVEL_MAX 16
#define CAM_CPAS_MAX_TREE_NODES 50

#define CAM_CPAS_MAX_FUSE_FEATURE 10
/**
 * struct cam_cpas_vdd_ahb_mapping : Voltage to ahb level mapping
 *
@@ -72,6 +72,21 @@ struct cam_cpas_tree_node {
	struct cam_cpas_tree_node *parent_node;
};

/**
 * struct cam_cpas_feature_info : Fuse feature information
 *
 * @feature      : feature
 * @enable       : feature is enabled or disabled
 * @hw_id        : hw id for this feature, it will be zero
 *                 if not applicable
 *
 */
struct cam_cpas_feature_info {
	uint32_t feature;
	uint32_t enable;
	uint32_t hw_id;
};

/**
 * struct cam_cpas_private_soc : CPAS private DT info
 *
@@ -90,7 +105,8 @@ struct cam_cpas_tree_node {
 * @camnoc_axi_clk_bw_margin : BW Margin in percentage to add while calculating
 *      camnoc axi clock
 * @camnoc_axi_min_ib_bw: Min camnoc BW which varies based on target
 * @feature_mask: feature mask value for hw supported features
 * @num_feature_entries: number of feature entries
 * @feature_info: fuse based feature info for hw supported features
 * @cx_ipeak_gpu_limit: Flag for Cx Ipeak GPU mitigation
 * @gpu_pwr_limit: Handle for Cx Ipeak GPU Mitigation
 *
@@ -109,7 +125,8 @@ struct cam_cpas_private_soc {
	uint32_t camnoc_bus_width;
	uint32_t camnoc_axi_clk_bw_margin;
	uint64_t camnoc_axi_min_ib_bw;
	uint32_t feature_mask;
	uint32_t num_feature_entries;
	struct cam_cpas_feature_info  feature_info[CAM_CPAS_MAX_FUSE_FEATURE];
	uint32_t cx_ipeak_gpu_limit;
	struct kgsl_pwr_limit *gpu_pwr_limit;
};
+7 −4
Original line number Diff line number Diff line
@@ -534,11 +534,14 @@ int cam_cpas_get_cpas_hw_version(
 *
 * @flag  : Camera hw features to check
 *
 * @return 1 if feature is supported
 * @hw_id  : HW id index, if hw id is not valid feature, send zero
 *
 * @return true if feature is supported
 *         false if feature is not supported
 *
 */
int cam_cpas_is_feature_supported(
	uint32_t flag);
bool cam_cpas_is_feature_supported(uint32_t flag,
	uint32_t hw_id);

/**
 * cam_cpas_axi_util_path_type_to_string()
+2 −1
Original line number Diff line number Diff line
@@ -4384,7 +4384,8 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
		goto err;
	}

	if (cam_cpas_is_feature_supported(CAM_CPAS_QCFA_BINNING_ENABLE) == 1)
	if (cam_cpas_is_feature_supported(CAM_CPAS_QCFA_BINNING_ENABLE,
		csid_idx) == true)
		ife_csid_hw->binning_enable = 1;

	ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
Loading