mmi_info: Update ram info for ddr5

Update ram info to handle ddr5, which uses a new
struct from the bootloader with an extra flag.

Also re-work error handling, previously it was possible
that if a wrong size is returned, the pointer to the
smem struct might not be null and we will still try
to access it, causing a panic. So, do not add the
sysfs entry if it is not correct.

Change-Id: Ib195543175528d0477266281080c4dc4a96abd3c
Signed-off-by: Ryan Lattrel <ryanl@motorola.com>
Reviewed-on: https://gerrit.mot.com/1402645
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Reviewed-by: Dong-Hua Yan <a18317@motorola.com>
Reviewed-by: Curtis Porter <porterc@motorola.com>
Tested-by: Jira Key
Reviewed-by: Konstantin Makariev <kmakariev@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Ryan Lattrel 2019-08-13 17:52:56 -05:00
commit 337e3fbc91

View file

@ -36,6 +36,15 @@ static struct {
unsigned int ramsize;
} *smem_ddr_info;
struct smem_ddr_info_v2 {
unsigned int mr5;
unsigned int mr6;
unsigned int mr7;
unsigned int mr8;
unsigned int ramsize;
unsigned int type;
};
static char sysfsram_type_name[20] = "unknown";
static char sysfsram_vendor_name[20] = "unknown";
static uint32_t sysfsram_ramsize;
@ -112,11 +121,53 @@ static struct attribute_group ram_info_properties_attr_group = {
static struct kobject *ram_info_properties_kobj;
static void parse_ddr_type(void)
{
uint32_t tid;
static const char *types[] = {
"S4 SDRAM",
"S2 SDRAM",
"N NVM",
"Reserved"
};
/* identify type */
tid = smem_ddr_info->mr8 & 0x03;
if (tid < ARRAY_SIZE(types)) {
snprintf(sysfsram_type_name, sizeof(sysfsram_type_name),
"%s", types[tid]);
}
}
static void parse_ddr_type_v2(struct smem_ddr_info_v2 *ddr_info)
{
uint32_t tid;
static const char *types[] = {
"No DDR",
"LPDDR1",
"LPDDR2",
"PCDDR2",
"PCDDR3",
"LPDDR3",
"LPDDR4",
"LPDDR4X",
"LPDDR5",
"LPDDR5X"
};
/* identify type */
tid = ddr_info->type;
if (tid < ARRAY_SIZE(types)) {
snprintf(sysfsram_type_name, sizeof(sysfsram_type_name),
"%s", types[tid]);
}
}
int mmi_ram_info_init(void)
{
int status = 0;
uint32_t vid, tid;
const char *tname = "unknown";
uint8_t is_v2 = 0;
uint32_t vid;
const char *vname = "unknown";
static const char *vendors[] = {
"unknown",
@ -135,63 +186,59 @@ int mmi_ram_info_init(void)
"ZMOS",
"Intel"
};
static const char *types[] = {
"S4 SDRAM",
"S2 SDRAM",
"N NVM",
"Reserved"
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
ssize_t ddr_info_size;
ssize_t ddr_info_size = 0;
smem_ddr_info = qcom_smem_get(QCOM_SMEM_HOST_ANY,
SMEM_SDRAM_INFO,
&ddr_info_size);
if (smem_ddr_info != NULL &&
sizeof(*smem_ddr_info) == ddr_info_size) {
if(smem_ddr_info) {
if(ddr_info_size < sizeof(*smem_ddr_info)) {
pr_err("%s: Invalid SMEM size, cannot get RAM info\n", __func__);
goto err;
}
/* v2 has an extra field */
if(ddr_info_size == sizeof(struct smem_ddr_info_v2))
is_v2 = 1;
}
#else
smem_ddr_info = smem_alloc(SMEM_SDRAM_INFO, sizeof(*smem_ddr_info), 0,
SMEM_ANY_HOST_FLAG);
if (smem_ddr_info != NULL) {
#endif
/* identify vendor */
vid = smem_ddr_info->mr5 & 0xFF;
if (vid < ARRAY_SIZE(vendors))
vname = vendors[vid];
else if (vid == 0xFE)
vname = "Numonyx";
else if (vid == 0xFF)
vname = "Micron";
snprintf(sysfsram_vendor_name, sizeof(sysfsram_vendor_name),
"%s", vname);
/* identify type */
tid = smem_ddr_info->mr8 & 0x03;
if (tid < ARRAY_SIZE(types))
tname = types[tid];
snprintf(sysfsram_type_name, sizeof(sysfsram_type_name),
"%s", tname);
/* extract size */
sysfsram_ramsize = smem_ddr_info->ramsize;
mmi_annotate_persist(
"RAM: %s, %s, %u MB, MR5:0x%02X, MR6:0x%02X, "
"MR7:0x%02X, MR8:0x%02X\n",
vname, tname, smem_ddr_info->ramsize,
smem_ddr_info->mr5, smem_ddr_info->mr6,
smem_ddr_info->mr7, smem_ddr_info->mr8);
} else {
/* complain, but do not fail if SMEM was not allocated */
/* defaults will be reported */
if (smem_ddr_info == NULL) {
pr_err("%s: failed to access RAM info in SMEM\n", __func__);
goto err;
}
/* identify vendor */
vid = smem_ddr_info->mr5 & 0xFF;
if (vid < ARRAY_SIZE(vendors))
vname = vendors[vid];
else if (vid == 0xFE)
vname = "Numonyx";
else if (vid == 0xFF)
vname = "Micron";
snprintf(sysfsram_vendor_name, sizeof(sysfsram_vendor_name),
"%s", vname);
if(is_v2)
parse_ddr_type_v2((struct smem_ddr_info_v2 *)smem_ddr_info);
else
parse_ddr_type();
/* extract size */
sysfsram_ramsize = smem_ddr_info->ramsize;
mmi_annotate_persist(
"RAM: %s, %s, %u MB, MR5:0x%02X, MR6:0x%02X, "
"MR7:0x%02X, MR8:0x%02X\n",
vname, sysfsram_type_name, smem_ddr_info->ramsize,
smem_ddr_info->mr5, smem_ddr_info->mr6,
smem_ddr_info->mr7, smem_ddr_info->mr8);
/* create sysfs object */
ram_info_properties_kobj = kobject_create_and_add("ram", NULL);
@ -201,9 +248,12 @@ int mmi_ram_info_init(void)
if (!ram_info_properties_kobj || status) {
pr_err("%s: failed to create /sys/ram\n", __func__);
return 1;
} else
return 0;
goto err;
}
return 0;
err:
return 1;
}
void mmi_ram_info_exit(void)