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

Commit c2862e08 authored by Naina Mehta's avatar Naina Mehta
Browse files

soc: qcom: socinfo: Add API for defective core/part information



Add kernel API to provide defective core and part information.
Also export the information via sysfs entries.

Change-Id: I984effd4247831412117c9d631225bdc2d9f1508
Signed-off-by: default avatarNaina Mehta <quic_nainmeht@quicinc.com>
parent 6920b254
Loading
Loading
Loading
Loading
+103 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <soc/qcom/socinfo.h>
#include <linux/soc/qcom/smem.h>
#include <soc/qcom/boot_stats.h>
#include <asm/unaligned.h>

#define BUILD_ID_LENGTH 32
#define CHIP_ID_LENGTH 32
@@ -870,6 +871,42 @@ msm_get_ncluster_array_offset(struct device *dev,
		socinfo_get_ncluster_array_offset());
}

uint32_t
socinfo_get_cluster_info(enum defective_cluster_type cluster)
{
	uint32_t def_cluster, num_cluster, offset;
	void *cluster_val;
	void *info = socinfo;

	if (cluster >= NUM_CLUSTERS_MAX) {
		pr_err("Bad cluster\n");
		return -EINVAL;
	}

	num_cluster = socinfo_get_num_clusters();
	offset = socinfo_get_ncluster_array_offset();

	if (!num_cluster || !offset)
		return -EINVAL;

	info += offset;
	cluster_val = info + (sizeof(uint32_t) * cluster);
	def_cluster = get_unaligned_le32(cluster_val);

	return def_cluster;
}
EXPORT_SYMBOL(socinfo_get_cluster_info);

static ssize_t
msm_get_defective_cores(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	uint32_t def_cluster = socinfo_get_cluster_info(CLUSTER_CPUSS);

	return scnprintf(buf, PAGE_SIZE, "%x\n", def_cluster);
}

static ssize_t
msm_get_num_defective_parts(struct device *dev,
			struct device_attribute *attr,
@@ -888,6 +925,60 @@ msm_get_ndefective_parts_array_offset(struct device *dev,
		socinfo_get_ndefective_parts_array_offset());
}

static uint32_t
socinfo_get_defective_parts(void)
{
	uint32_t num_parts = socinfo_get_num_defective_parts();
	uint32_t offset = socinfo_get_ndefective_parts_array_offset();
	uint32_t def_parts = 0;
	void *info = socinfo;
	uint32_t part_entry;
	int i;

	if (!num_parts || !offset)
		return -EINVAL;

	info += offset;
	for (i = 0; i < num_parts; i++) {
		part_entry = get_unaligned_le32(info);
		if (part_entry)
			def_parts |= BIT(i);
		info += sizeof(uint32_t);
	}

	return def_parts;
}

bool
socinfo_get_part_info(enum defective_part_type part)
{
	uint32_t partinfo;

	if (part >= NUM_PARTS_MAX) {
		pr_err("Bad part number\n");
		return false;
	}

	partinfo = socinfo_get_defective_parts();
	if (partinfo < 0) {
		pr_err("Failed to get part information\n");
		return false;
	}

	return (partinfo & BIT(part));
}
EXPORT_SYMBOL(socinfo_get_part_info);

static ssize_t
msm_get_defective_parts(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	uint32_t def_parts = socinfo_get_defective_parts();

	return scnprintf(buf, PAGE_SIZE, "%x\n", def_parts);
}

static ssize_t
msm_get_nmodem_supported(struct device *dev,
			struct device_attribute *attr,
@@ -1192,6 +1283,10 @@ static struct device_attribute msm_soc_attr_ncluster_array_offset =
	__ATTR(ncluster_array_offset, 0444,
			msm_get_ncluster_array_offset, NULL);

static struct device_attribute msm_soc_attr_defective_cores =
	__ATTR(defective_cores, 0444,
			msm_get_defective_cores, NULL);

static struct device_attribute msm_soc_attr_num_defective_parts =
	__ATTR(num_defective_parts, 0444,
			msm_get_num_defective_parts, NULL);
@@ -1200,6 +1295,10 @@ static struct device_attribute msm_soc_attr_ndefective_parts_array_offset =
	__ATTR(ndefective_parts_array_offset, 0444,
			msm_get_ndefective_parts_array_offset, NULL);

static struct device_attribute msm_soc_attr_defective_parts =
	__ATTR(defective_parts, 0444,
			msm_get_defective_parts, NULL);

static struct device_attribute msm_soc_attr_nmodem_supported =
	__ATTR(nmodem_supported, 0444,
			msm_get_nmodem_supported, NULL);
@@ -1398,10 +1497,14 @@ static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
					&msm_soc_attr_num_clusters);
		device_create_file(msm_soc_device,
					&msm_soc_attr_ncluster_array_offset);
		device_create_file(msm_soc_device,
					&msm_soc_attr_defective_cores);
		device_create_file(msm_soc_device,
					&msm_soc_attr_num_defective_parts);
		device_create_file(msm_soc_device,
				&msm_soc_attr_ndefective_parts_array_offset);
		device_create_file(msm_soc_device,
					&msm_soc_attr_defective_parts);
	case SOCINFO_VERSION(0, 13):
		 device_create_file(msm_soc_device,
					&msm_soc_attr_nproduct_id);
+26 −0
Original line number Diff line number Diff line
@@ -233,6 +233,30 @@ enum pmic_model {
	PMIC_MODEL_UNKNOWN	= 0xFFFFFFFF
};

enum defective_part_type {
	PART_UNKNOWN      = 0,
	PART_GPU          = 1,
	PART_VIDEO        = 2,
	PART_CAMERA       = 3,
	PART_DISPLAY      = 4,
	PART_AUDIO        = 5,
	PART_MODEM        = 6,
	PART_WLAN         = 7,
	PART_COMP         = 8,
	PART_SENSORS      = 9,
	PART_NPU          = 10,
	PART_SPSS         = 11,
	PART_NAV          = 12,
	PART_COMP1        = 13,
	PART_DISPLAY1     = 14,
	NUM_PARTS_MAX,
};

enum defective_cluster_type {
	CLUSTER_CPUSS      = 0,
	NUM_CLUSTERS_MAX,
};

enum msm_cpu socinfo_get_msm_cpu(void);
uint32_t socinfo_get_id(void);
uint32_t socinfo_get_version(void);
@@ -243,6 +267,8 @@ uint32_t socinfo_get_platform_type(void);
uint32_t socinfo_get_platform_subtype(void);
uint32_t socinfo_get_platform_version(void);
uint32_t socinfo_get_serial_number(void);
uint32_t socinfo_get_cluster_info(enum defective_cluster_type cluster);
bool socinfo_get_part_info(enum defective_part_type part);
enum pmic_model socinfo_get_pmic_model(void);
uint32_t socinfo_get_pmic_die_revision(void);
int __init socinfo_init(void) __must_check;