msm8660: Add support to detect 8660 charm target

Read socinfo to detect if target is a charm target. Use this
information along with hardware platform information to use the
right machine id for Linux kernel.

Change-Id: Ibf536f8f0a6e44e99336d6d054f9fda588a58608
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 98697e4..2b404f7 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -82,14 +82,39 @@
     unsigned buffer_align; //Need for 8 bytes alignment while reading from shared memory.
 };
 
+struct smem_board_info_v5
+{
+    struct smem_board_info_v3 board_info_v3;
+    unsigned platform_version;
+    unsigned fused_chip;
+};
+
+/* chip information */
+enum {
+    UNKNOWN = 0,
+    MDM9200 = 57,
+    MDM9600 = 58,
+};
+
+enum platform
+{
+    HW_PLATFORM_UNKNOWN = 0,
+    HW_PLATFORM_SURF    = 1,
+    HW_PLATFORM_FFA     = 2,
+    HW_PLATFORM_FLUID   = 3,
+    HW_PLATFORM_SVLTE   = 4,
+    HW_PLATFORM_32BITS  = 0x7FFFFFFF
+};
+
+
 typedef enum {
 	SMEM_SPINLOCK_ARRAY = 7,
 
 	SMEM_AARM_PARTITION_TABLE = 9,
 
-        SMEM_APPS_BOOT_MODE = 106,
+	SMEM_APPS_BOOT_MODE = 106,
 
-        SMEM_BOARD_INFO_LOCATION = 137,
+	SMEM_BOARD_INFO_LOCATION = 137,
 
 	SMEM_USABLE_RAM_PARTITION_TABLE = 402,
 
diff --git a/target/msm7630_surf/init.c b/target/msm7630_surf/init.c
index 371ad1e..f05c728 100644
--- a/target/msm7630_surf/init.c
+++ b/target/msm7630_surf/init.c
@@ -52,17 +52,6 @@
 #define MSM8655_ID                 75
 #define APQ8055_ID                 85
 
-//Enum values for 7x30 target platforms.
-enum platform
-{
-    HW_PLATFORM_UNKNOWN = 0,
-    HW_PLATFORM_SURF    = 1,
-    HW_PLATFORM_FFA     = 2,
-    HW_PLATFORM_FLUID   = 3,
-    HW_PLATFORM_SVLTE   = 4,
-    HW_PLATFORM_32BITS  = 0x7FFFFFFF
-};
-
 #define VARIABLE_LENGTH        0x10101010
 #define DIFF_START_ADDR        0xF0F0F0F0
 #define NUM_PAGES_PER_BLOCK    0x40
diff --git a/target/msm8660_surf/init.c b/target/msm8660_surf/init.c
index 9a64641..ae414dc 100755
--- a/target/msm8660_surf/init.c
+++ b/target/msm8660_surf/init.c
@@ -42,6 +42,8 @@
 #define LINUX_MACHTYPE_8660_SURF    1009002
 #define LINUX_MACHTYPE_8660_FFA     1009003
 #define LINUX_MACHTYPE_8660_FLUID   1009004
+#define LINUX_MACHTYPE_8660_CHARM_SURF   3181
+#define LINUX_MACHTYPE_8660_CHARM_FFA    3199
 
 void keypad_init(void);
 
@@ -73,28 +75,85 @@
 
 unsigned board_machtype(void)
 {
-    unsigned id = platform_id_read();
-    switch(id)
-    {
-        case 0x1:
-            return LINUX_MACHTYPE_8660_SURF;
-        case 0x2:
-            return LINUX_MACHTYPE_8660_FFA;
-        case 0x3:
-            return LINUX_MACHTYPE_8660_FLUID;
-        default:
-            /* Writing to Debug LED register and reading back to auto detect
-            SURF and FFA. If we read back, it is SURF */
-            debug_led_write(0xA5);
+	struct smem_board_info_v5 board_info_v5;
+	unsigned int board_info_len = 0;
+	unsigned smem_status = 0;
+	unsigned format = 0;
+	unsigned id = 0;
+	unsigned hw_platform = 0;
+	unsigned fused_chip = 0;
+	unsigned mach_id = LINUX_MACHTYPE_8660_FFA;
 
-            if((debug_led_read() & 0xFF) == 0xA5)
-            {
-                debug_led_write(0);
-                return LINUX_MACHTYPE_8660_SURF;
-            }
-            else
-                return LINUX_MACHTYPE_8660_FFA;
-    };
+	/* Detect external msm if this is a "fusion" */
+	smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
+					&format, sizeof(format), 0);
+	if(!smem_status)
+	{
+		if (format >= 5)
+		{
+			board_info_len = sizeof(board_info_v5);
+
+			smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
+							&board_info_v5, board_info_len);
+			if(!smem_status)
+			{
+				fused_chip = board_info_v5.fused_chip;
+			}
+		}
+	}
+
+	/* Detect SURF v/s FFA v/s Fluid */
+	id = board_info_v5.board_info_v3.hw_platform;
+	switch(id)
+	{
+		case 0x1:
+			hw_platform = HW_PLATFORM_SURF;
+			break;
+		case 0x2:
+			hw_platform = HW_PLATFORM_FFA;
+			break;
+		case 0x3:
+			hw_platform = HW_PLATFORM_FLUID;
+			break;
+		default:
+			/* Writing to Debug LED register and reading back to auto detect
+			SURF and FFA. If we read back, it is SURF */
+			debug_led_write(0xA5);
+
+			if((debug_led_read() & 0xFF) == 0xA5)
+			{
+				debug_led_write(0);
+				hw_platform = HW_PLATFORM_SURF;
+			}
+			else
+				hw_platform = HW_PLATFORM_FFA;
+	};
+
+	/* Use hw_platform and fused_chip information to determine machine id */
+	switch(fused_chip)
+	{
+		case UNKNOWN:
+			if (hw_platform == HW_PLATFORM_SURF)
+				mach_id = LINUX_MACHTYPE_8660_SURF;
+			else if (hw_platform == HW_PLATFORM_FFA)
+				mach_id = LINUX_MACHTYPE_8660_FFA;
+			else if (hw_platform == HW_PLATFORM_FLUID)
+				mach_id = LINUX_MACHTYPE_8660_FLUID;
+			break;
+
+		case MDM9200:
+		case MDM9600:
+			if (hw_platform == HW_PLATFORM_SURF)
+				mach_id = LINUX_MACHTYPE_8660_CHARM_SURF;
+			else if (hw_platform == HW_PLATFORM_FFA)
+				mach_id = LINUX_MACHTYPE_8660_CHARM_FFA;
+			break;
+
+		default:
+			mach_id = LINUX_MACHTYPE_8660_FFA;
+	}
+
+	return mach_id;
 }
 
 void reboot_device(unsigned reboot_reason)