diff --git a/drivers/mmi_info/mmi_ram_info.c b/drivers/mmi_info/mmi_ram_info.c index fe11b1b4b55b..d3b7c3ed8ddd 100644 --- a/drivers/mmi_info/mmi_ram_info.c +++ b/drivers/mmi_info/mmi_ram_info.c @@ -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)