Merge "soc: qcom: socinfo: correct partid conditional check"

This commit is contained in:
qctecmdr 2022-09-15 14:55:19 -07:00 committed by Gerrit - the friendly Code Review server
commit 2bd9e0a08f
2 changed files with 279 additions and 4 deletions

View File

@ -114,6 +114,7 @@ static const char *const pmic_models[] = {
#endif /* CONFIG_DEBUG_FS */
static uint32_t socinfo_format;
static const char *sku;
enum {
HW_PLATFORM_UNKNOWN = 0,
@ -195,6 +196,37 @@ static const char * const hw_platform_subtype[] = {
[PLATFORM_SUBTYPE_INVALID] = "Invalid",
};
static const char * const hw_platform_feature_code[] = {
[SOCINFO_FC_UNKNOWN] = "Unknown",
[SOCINFO_FC_AA] = "AA",
[SOCINFO_FC_AB] = "AB",
[SOCINFO_FC_AC] = "AC",
[SOCINFO_FC_AD] = "AD",
[SOCINFO_FC_AE] = "AE",
[SOCINFO_FC_AF] = "AF",
[SOCINFO_FC_AG] = "AG",
[SOCINFO_FC_AH] = "AH",
};
static const char * const hw_platform_ifeature_code[] = {
[SOCINFO_FC_Y0 - SOCINFO_FC_Y0] = "Y0",
[SOCINFO_FC_Y1 - SOCINFO_FC_Y0] = "Y1",
[SOCINFO_FC_Y2 - SOCINFO_FC_Y0] = "Y2",
[SOCINFO_FC_Y3 - SOCINFO_FC_Y0] = "Y3",
[SOCINFO_FC_Y4 - SOCINFO_FC_Y0] = "Y4",
[SOCINFO_FC_Y5 - SOCINFO_FC_Y0] = "Y5",
[SOCINFO_FC_Y6 - SOCINFO_FC_Y0] = "Y6",
[SOCINFO_FC_Y7 - SOCINFO_FC_Y0] = "Y7",
[SOCINFO_FC_Y8 - SOCINFO_FC_Y0] = "Y8",
[SOCINFO_FC_Y9 - SOCINFO_FC_Y0] = "Y9",
[SOCINFO_FC_YA - SOCINFO_FC_Y0] = "YA",
[SOCINFO_FC_YB - SOCINFO_FC_Y0] = "YB",
[SOCINFO_FC_YC - SOCINFO_FC_Y0] = "YC",
[SOCINFO_FC_YD - SOCINFO_FC_Y0] = "YD",
[SOCINFO_FC_YE - SOCINFO_FC_Y0] = "YE",
[SOCINFO_FC_YF - SOCINFO_FC_Y0] = "YF",
};
/* Socinfo SMEM item structure */
struct socinfo {
__le32 fmt;
@ -242,12 +274,20 @@ struct socinfo {
/* Version 15 */
__le32 nmodem_supported;
/* Version 16 */
__le32 esku;
__le32 nproduct_code;
__le32 feature_code;
__le32 pcode;
__le32 npartnamemap_offset;
__le32 nnum_partname_mapping;
} *socinfo;
#define PART_NAME_MAX 32
struct socinfo_partinfo {
__le32 part_type;
char part_name[PART_NAME_MAX];
__le32 part_name_len;
};
struct socinfo_partinfo partinfo[SOCINFO_PART_MAX_PARTTYPE];
#ifdef CONFIG_DEBUG_FS
struct socinfo_params {
u32 raw_device_family;
@ -444,6 +484,47 @@ static uint32_t socinfo_get_nmodem_supported(void)
: 0;
}
/* Version 16 */
static uint32_t socinfo_get_feature_code_id(void)
{
uint32_t fc_id;
if (!socinfo || socinfo_format < SOCINFO_VERSION(0, 16))
return SOCINFO_FC_UNKNOWN;
fc_id = le32_to_cpu(socinfo->feature_code);
if (fc_id <= SOCINFO_FC_UNKNOWN || fc_id >= SOCINFO_FC_INT_RESERVE)
return SOCINFO_FC_UNKNOWN;
return fc_id;
}
static const char *socinfo_get_feature_code_mapping(void)
{
uint32_t id = socinfo_get_feature_code_id();
if (id > SOCINFO_FC_UNKNOWN && id < SOCINFO_FC_EXT_RESERVE)
return hw_platform_feature_code[id];
else if (id >= SOCINFO_FC_Y0 && id < SOCINFO_FC_INT_RESERVE)
return hw_platform_ifeature_code[id - SOCINFO_FC_Y0];
return NULL;
}
static uint32_t socinfo_get_pcode_id(void)
{
uint32_t pcode;
if (!socinfo || socinfo_format < SOCINFO_VERSION(0, 16))
return SOCINFO_PCODE_RESERVE;
pcode = le32_to_cpu(socinfo->pcode);
if (pcode <= SOCINFO_PCODE_UNKNOWN || pcode >= SOCINFO_PCODE_RESERVE)
return SOCINFO_PCODE_UNKNOWN;
return pcode;
}
/* Version 2 */
static ssize_t
msm_get_raw_id(struct device *dev,
@ -680,6 +761,36 @@ msm_get_nmodem_supported(struct device *dev,
}
ATTR_DEFINE(nmodem_supported);
/* Version 16 */
static ssize_t
msm_get_sku(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sysfs_emit(buf, "%s\n", sku ? sku : "Unknown");
}
ATTR_DEFINE(sku);
static ssize_t
msm_get_pcode(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return scnprintf(buf, PAGE_SIZE, "0x%x\n", socinfo_get_pcode_id());
}
ATTR_DEFINE(pcode);
static ssize_t
msm_get_feature_code(struct device *dev,
struct device_attribute *attr,
char *buf)
{
const char *feature_code = socinfo_get_feature_code_mapping();
return sysfs_emit(buf, "%s\n", feature_code ? feature_code : "Unknown");
}
ATTR_DEFINE(feature_code);
struct qcom_socinfo {
struct soc_device *soc_dev;
struct soc_device_attribute attr;
@ -1076,6 +1187,9 @@ static void socinfo_populate_sysfs(struct qcom_socinfo *qcom_socinfo)
switch (socinfo_format) {
case SOCINFO_VERSION(0, 16):
msm_custom_socinfo_attrs[i++] = &dev_attr_sku.attr;
msm_custom_socinfo_attrs[i++] = &dev_attr_feature_code.attr;
msm_custom_socinfo_attrs[i++] = &dev_attr_pcode.attr;
fallthrough;
case SOCINFO_VERSION(0, 15):
msm_custom_socinfo_attrs[i++] = &dev_attr_nmodem_supported.attr;
@ -1363,7 +1477,7 @@ static void socinfo_print(void)
break;
case SOCINFO_VERSION(0, 16):
pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_defective_parts=0x%x ndefective_parts_array_offset=0x%x nmodem_supported=0x%x\n",
pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_defective_parts=0x%x ndefective_parts_array_offset=0x%x nmodem_supported=0x%x feature_code=0x%x pcode=0x%x sku=%s\n",
f_maj, f_min, socinfo->id, v_maj, v_min,
socinfo->raw_id, socinfo->raw_ver,
socinfo->hw_plat,
@ -1383,7 +1497,10 @@ static void socinfo_print(void)
socinfo->ncluster_array_offset,
socinfo->num_defective_parts,
socinfo->ndefective_parts_array_offset,
socinfo->nmodem_supported);
socinfo->nmodem_supported,
socinfo->feature_code,
socinfo->pcode,
sku ? sku : "Unknown");
break;
default:
@ -1424,6 +1541,74 @@ uint32_t socinfo_get_serial_number(void)
}
EXPORT_SYMBOL(socinfo_get_serial_number);
int socinfo_get_feature_code(void)
{
if (socinfo_format < SOCINFO_VERSION(0, 16)) {
pr_warn("socinfo: Feature code is not supported by bootloaders\n");
return -EINVAL;
}
return socinfo_get_feature_code_id();
}
EXPORT_SYMBOL(socinfo_get_feature_code);
int socinfo_get_pcode(void)
{
if (socinfo_format < SOCINFO_VERSION(0, 16)) {
pr_warn("socinfo: pcode is not supported by bootloaders\n");
return -EINVAL;
}
return socinfo_get_pcode_id();
}
EXPORT_SYMBOL(socinfo_get_pcode);
char *socinfo_get_partinfo_details(unsigned int part_id)
{
if (socinfo_format < SOCINFO_VERSION(0, 16) || part_id >= SOCINFO_PART_MAX_PARTTYPE)
return NULL;
return partinfo[part_id].part_name;
}
EXPORT_SYMBOL(socinfo_get_partinfo_details);
void socinfo_enumerate_partinfo_details(void)
{
unsigned int partinfo_array_offset;
unsigned int nnum_partname_mapping;
void *ptr = socinfo;
int i, part_type, part_name_len;
if (socinfo_format < SOCINFO_VERSION(0, 16))
return;
partinfo_array_offset = le32_to_cpu(socinfo->npartnamemap_offset);
nnum_partname_mapping = le32_to_cpu(socinfo->nnum_partname_mapping);
if (nnum_partname_mapping > SOCINFO_PART_MAX_PARTTYPE) {
pr_warn("socinfo: Mismatch between bootloaders and hlos\n");
return;
}
ptr += partinfo_array_offset;
for (i = 0; i < nnum_partname_mapping; i++) {
part_type = get_unaligned_le32(ptr);
if (part_type > SOCINFO_PART_MAX_PARTTYPE)
pr_warn("socinfo: part type mismatch\n");
partinfo[part_type].part_type = part_type;
ptr += sizeof(u32);
strscpy(partinfo[part_type].part_name, ptr, PART_NAME_MAX);
part_name_len = strlen(partinfo[part_type].part_name);
ptr += PART_NAME_MAX;
if (part_name_len != get_unaligned_le32(ptr))
pr_warn("socinfo: part info string length mismatch\n");
partinfo[part_type].part_name_len = part_name_len;
ptr += sizeof(u32);
}
}
#ifdef CONFIG_DEBUG_FS
#define QCOM_OPEN(name, _func) \
@ -1703,6 +1888,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
struct qcom_socinfo *qs;
struct socinfo *info;
size_t item_size;
const char *machine, *fc;
info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID,
&item_size);
@ -1730,6 +1916,14 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
if (offsetof(struct socinfo, serial_num) <= item_size)
qs->attr.serial_number = kasprintf(GFP_KERNEL, "%u", socinfo_get_serial_number());
if (socinfo_format >= SOCINFO_VERSION(0, 16)) {
socinfo_enumerate_partinfo_details();
machine = socinfo_machine(&pdev->dev, le32_to_cpu(info->id));
fc = socinfo_get_feature_code_mapping();
sku = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%u-%s",
machine, socinfo_get_pcode_id(), fc);
}
qsocinfo = qs;
init_rwsem(&qs->current_image_rwsem);
socinfo_populate_sysfs(qs);

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __SOC_QCOM_SOCINFO_H__
@ -8,10 +9,78 @@
#include <linux/types.h>
enum feature_code {
/* External feature code */
SOCINFO_FC_UNKNOWN = 0x0,
SOCINFO_FC_AA,
SOCINFO_FC_AB,
SOCINFO_FC_AC,
SOCINFO_FC_AD,
SOCINFO_FC_AE,
SOCINFO_FC_AF,
SOCINFO_FC_AG,
SOCINFO_FC_AH,
SOCINFO_FC_EXT_RESERVE,
/* Internal feature code */
SOCINFO_FC_Y0 = 0xf1,
SOCINFO_FC_Y1,
SOCINFO_FC_Y2,
SOCINFO_FC_Y3,
SOCINFO_FC_Y4,
SOCINFO_FC_Y5,
SOCINFO_FC_Y6,
SOCINFO_FC_Y7,
SOCINFO_FC_Y8,
SOCINFO_FC_Y9,
SOCINFO_FC_YA,
SOCINFO_FC_YB,
SOCINFO_FC_YC,
SOCINFO_FC_YD,
SOCINFO_FC_YE,
SOCINFO_FC_YF,
SOCINFO_FC_INT_RESERVE
};
enum pcode {
SOCINFO_PCODE_UNKNOWN = 0,
SOCINFO_PCODE_0,
SOCINFO_PCODE_1,
SOCINFO_PCODE_2,
SOCINFO_PCODE_3,
SOCINFO_PCODE_4,
SOCINFO_PCODE_5,
SOCINFO_PCODE_6,
SOCINFO_PCODE_7,
SOCINFO_PCODE_8,
SOCINFO_PCODE_RESERVE = 0x7fffffff
};
enum socinfo_parttype {
SOCINFO_PART_GPU,
SOCINFO_PART_VIDEO,
SOCINFO_PART_CAMERA,
SOCINFO_PART_DISPLAY,
SOCINFO_PART_AUDIO,
SOCINFO_PART_MODEM,
SOCINFO_PART_WLAN,
SOCINFO_PART_COMP,
SOCINFO_PART_SENSORS,
SOCINFO_PART_NPU,
SOCINFO_PART_SPSS,
SOCINFO_PART_NAV,
SOCINFO_PART_COMPUTE_1,
SOCINFO_PART_DISPLAY_1,
SOCINFO_PART_MAX_PARTTYPE
};
#if IS_ENABLED(CONFIG_QCOM_SOCINFO)
uint32_t socinfo_get_id(void);
uint32_t socinfo_get_serial_number(void);
const char *socinfo_get_id_string(void);
int socinfo_get_feature_code(void);
int socinfo_get_pcode(void);
char *socinfo_get_partinfo_details(unsigned int part_id);
#else
static inline uint32_t socinfo_get_id(void)
{
@ -27,6 +96,18 @@ static inline const char *socinfo_get_id_string(void)
{
return "N/A";
}
int socinfo_get_feature_code(void)
{
return -EINVAL;
}
int socinfo_get_pcode(void)
{
return -EINVAL;
}
const char *socinfo_get_partinfo_details(unsigned int part_id)
{
return NULL;
}
#endif /* CONFIG_QCOM_SOCINFO */
#endif /* __SOC_QCOM_SOCINFO_H__ */