platform: msm_shared: Add support for smem v11

Add support for smem v11

Change-Id: Id9af92220695a0efb3bf6c4f80f5b8eaa91ee3c7
diff --git a/platform/msm_shared/board.c b/platform/msm_shared/board.c
index 03f794c..1265f29 100644
--- a/platform/msm_shared/board.c
+++ b/platform/msm_shared/board.c
@@ -33,6 +33,9 @@
 #include <baseband.h>
 #include <boot_device.h>
 
+static uint16_t format_major = 0;
+static uint16_t format_minor = 0;
+
 static struct board_data board = {UNKNOWN,
 	0,
 	0,
@@ -44,6 +47,9 @@
 	{{PMIC_IS_INVALID, 0, 0}, {PMIC_IS_INVALID, 0, 0},
 	{PMIC_IS_INVALID, 0, 0}},
 	0,
+	0,
+	0,
+	NULL,
 };
 
 static void platform_detect()
@@ -53,13 +59,12 @@
 	struct smem_board_info_v8 board_info_v8;
 	struct smem_board_info_v9 board_info_v9;
 	struct smem_board_info_v10 board_info_v10;
+	struct smem_board_info_v11 board_info_v11;
 	unsigned int board_info_len = 0;
 	unsigned ret = 0;
 	unsigned format = 0;
 	unsigned pmic_type = 0;
 	uint8_t i;
-	uint16_t format_major = 0;
-	uint16_t format_minor = 0;
 
 	ret = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
 						   &format, sizeof(format), 0);
@@ -192,7 +197,7 @@
 			}
 			board.foundry_id = board_info_v9.foundry_id;
 		}
-		else if (format_minor >= 0xA)
+		else if (format_minor == 0xA)
 		{
 			board_info_len = sizeof(board_info_v10);
 
@@ -236,6 +241,37 @@
 			board.foundry_id = board_info_v10.foundry_id;
 			board.chip_serial = board_info_v10.chip_serial;
 		}
+		else if (format_minor >= 0xB)
+		{
+			board_info_len = sizeof(board_info_v11);
+
+			ret = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
+					&board_info_v11,
+					board_info_len);
+			if (ret)
+				return;
+
+			board.platform = board_info_v11.board_info_v3.msm_id;
+			board.platform_version = board_info_v11.board_info_v3.msm_version;
+			board.platform_hw = board_info_v11.board_info_v3.hw_platform;
+			board.platform_subtype = board_info_v11.platform_subtype;
+			/*
+			 * fill in board.target with variant_id information
+			 * bit no         |31  24 |23             16|15              8|7         0|
+			 * board.target = |subtype|plat_hw_ver major|plat_hw_ver minor|hw_platform|
+			 *
+			 */
+
+			board.target = (((board_info_v11.platform_subtype & 0xff) << 24) |
+						   (((board_info_v11.platform_version >> 16) & 0xff) << 16) |
+						   ((board_info_v11.platform_version & 0xff) << 8) |
+						   (board_info_v11.board_info_v3.hw_platform & 0xff));
+
+			board.foundry_id = board_info_v11.foundry_id;
+			board.chip_serial = board_info_v11.chip_serial;
+			board.num_pmics = board_info_v11.num_pmics;
+			board.pmic_array_offset = board_info_v11.pmic_array_offset;
+		}
 
 		/* HLOS subtype
 		 * bit no                        |31    20 | 19        16|15    13 |12      11 | 10          8 | 7     0|
@@ -251,6 +287,58 @@
 	}
 }
 
+void pmic_info_populate()
+{
+	struct smem_board_info_v11 *bi_v11=NULL;
+	unsigned int board_info_len = 0;
+	unsigned ret = 0;
+	uint32_t pmic_type = 0;
+
+	if (format_minor < 0xB)
+	{
+		// not needed for smem versions < 0xB
+		return;
+	}
+
+	board_info_len = sizeof(struct smem_board_info_v11) + board.num_pmics * sizeof(struct smem_pmic_info);
+	if(!(bi_v11 = malloc(board_info_len)))
+	{
+		dprintf(CRITICAL, "Error allocating memory for board structure\n");
+		ASSERT(0);
+	}
+	ret = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
+					bi_v11,
+					board_info_len);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Error reading from SMEM for populating pmic info\n");
+		goto free_bi_v11;
+	}
+
+	if(!(board.pmic_info_array = malloc(board.num_pmics * sizeof(struct board_pmic_data))))
+	{
+		dprintf(CRITICAL, "Error allocating memory for pmic info array\n");
+		ASSERT(0);
+	}
+	struct board_pmic_data *info = board.pmic_info_array;
+	for (uint8_t i = 0; i < board.num_pmics; i++)
+	{
+		memcpy(info, (void *)(bi_v11) + board.pmic_array_offset + (i * sizeof(struct smem_pmic_info)), sizeof(struct smem_pmic_info));
+		/*
+		 * fill in pimc_board_info with pmic type and pmic version information
+		 * bit no  		  	    |31  24|23         16|15          8|7		 0|
+		 * pimc_board_info =    |Unused|Major version|Minor version|PMIC_MODEL|
+		 *
+		 */
+		pmic_type = info->pmic_type == PMIC_IS_INVALID? 0 : info->pmic_type;
+		info->pmic_target = (((info->pmic_version >> 16) & 0xff) << 16) |
+			   ((info->pmic_version & 0xff) << 8) | (pmic_type & 0xff);
+		info++;
+	}
+free_bi_v11:
+	free(bi_v11);
+}
+
 void board_init()
 {
 	platform_detect();
@@ -296,21 +384,35 @@
 uint8_t board_pmic_info(struct board_pmic_data *info, uint8_t num_ent)
 {
 	uint8_t i;
-
-	for (i = 0; i < num_ent && i < SMEM_MAX_PMIC_DEVICES; i++) {
-		info->pmic_type = board.pmic_info[i].pmic_type;
-		info->pmic_version = board.pmic_info[i].pmic_version;
-		info->pmic_target = board.pmic_info[i].pmic_target;
-		info++;
+	if (format_major == 0x0)
+	{
+		if (format_minor < 0xB)
+		{
+			for (i = 0; i < num_ent && i < SMEM_MAX_PMIC_DEVICES; i++) {
+				info->pmic_type = board.pmic_info[i].pmic_type;
+				info->pmic_version = board.pmic_info[i].pmic_version;
+				info->pmic_target = board.pmic_info[i].pmic_target;
+				info++;
+			}
+			return (i--);
+		}
 	}
-
-	return (i--);
+	return 0;
 }
 
 uint32_t board_pmic_target(uint8_t num_ent)
 {
-	if (num_ent < SMEM_MAX_PMIC_DEVICES) {
-		return board.pmic_info[num_ent].pmic_target;
+	if (format_major == 0x0 && num_ent < SMEM_MAX_PMIC_DEVICES)
+	{
+		if (format_minor < 0xB && num_ent < SMEM_V8_SMEM_MAX_PMIC_DEVICES)
+		{
+			return board.pmic_info[num_ent].pmic_target;
+		}
+		else
+		{
+			if (num_ent < board.num_pmics)
+				return  board.pmic_info_array[num_ent].pmic_target;
+		}
 	}
 	return 0;
 }