Merge "aboot: lib: platform: Fix for banned apis"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 973e4a2..e15879d 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -3011,6 +3011,12 @@
 normal_boot:
 	if (!boot_into_fastboot)
 	{
+#ifdef MDTP_SUPPORT
+			/* Go through Firmware Lock verification before continue with boot process */
+			mdtp_fwlock_verify_lock();
+			display_image_on_screen();
+#endif /* MDTP_SUPPORT */
+
 		if (target_is_emmc_boot())
 		{
 			if(emmc_recovery_init())
@@ -3028,12 +3034,6 @@
 				}
 			}
 
-#ifdef MDTP_SUPPORT
-			/* Go through Firmware Lock verification before continue with boot process */
-			mdtp_fwlock_verify_lock();
-			display_image_on_screen();
-#endif /* MDTP_SUPPORT */
-
 			boot_linux_from_mmc();
 		}
 		else
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 160f6c8..5c5782a 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -44,10 +44,22 @@
 #define DIP_ENCRYPT 0
 #define DIP_DECRYPT 1
 
+#define MDTP_MAJOR_VERSION (0)
+#define MDTP_MINOR_VERSION (2)
+
+/** Extract major version number from complete version. */
+#define MDTP_GET_MAJOR_VERSION(version) ((version) >> 16)
+
+static int is_mdtp_activated = -1;
+
 static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
 
-static int is_mdtp_activated = -1;
+uint32_t g_mdtp_version = (((MDTP_MAJOR_VERSION << 16) & 0xFFFF0000) | (MDTP_MINOR_VERSION & 0x0000FFFF));
+
+int scm_random(uint32_t * rbuf, uint32_t  r_len);
+int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+
 /********************************************************************************/
 
 /* Read the DIP from EMMC */
@@ -102,7 +114,7 @@
 
 	if(mmc_write(ptn, ROUNDUP(sizeof(DIP_t), block_size), (void *)dip))
 	{
-		dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot read DIP info\n");
+		dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot write DIP info\n");
 		return -1;
 	}
 
@@ -136,6 +148,7 @@
 	memset(dec_dip, 0, sizeof(DIP_t));
 
 	dec_dip->status = DIP_STATUS_DEACTIVATED;
+	dec_dip->version = g_mdtp_version;
 
 	ret = mdtp_tzbsp_enc_hash_DIP(dec_dip, enc_dip);
 	if(ret < 0)
@@ -157,19 +170,20 @@
 }
 
 /* Validate a hash calculated on entire given partition */
-static int verify_partition_single_hash(char *name, uint32_t size, DIP_hash_table_entry_t *hash_table)
+static int verify_partition_single_hash(char *name, uint64_t size, DIP_hash_table_entry_t *hash_table)
 {
-	unsigned char digest[32]={0};
+	unsigned char digest[HASH_LEN]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
 	unsigned char *buf = (unsigned char *)target_get_scratch_address();
 	uint32_t block_size = mmc_get_device_blocksize();
-	uint32_t actual_partition_size = ROUNDUP(size, block_size);
+	uint64_t actual_partition_size = ROUNDUP(size, block_size);
 
-	dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
+	dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %llu\n", name, size);
 
 	ASSERT(name != NULL);
 	ASSERT(hash_table != NULL);
+	ASSERT(size > 0);
 
 	index = partition_get_index(name);
 	ptn = partition_get_offset(index);
@@ -181,15 +195,15 @@
 
 	if (mmc_read(ptn, (void *)buf, actual_partition_size))
 	{
-		dprintf(CRITICAL, "mdtp: verify_partition__single_hash: %s: mmc_read() fail.\n", name);
+		dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: mmc_read() fail.\n", name);
 		return -1;
 	}
 
 	/* calculating the hash value using HW crypto */
 	target_crypto_init_params();
-	hash_find(buf, size, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
+	hash_find(buf, size, digest, CRYPTO_AUTH_ALG_SHA256);
 
-	if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
+	if (memcmp(digest, hash_table->hash, HASH_LEN))
 	{
 		dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: Failed partition hash verification\n", name);
 
@@ -203,23 +217,27 @@
 
 /* Validate a hash table calculated per block of a given partition */
 static int verify_partition_block_hash(char *name,
-								uint32_t size,
-								uint32_t total_num_blocks,
+								uint64_t size,
 								uint32_t verify_num_blocks,
 								DIP_hash_table_entry_t *hash_table,
-							    uint8_t *force_verify_block)
+								uint8_t *force_verify_block)
 {
-	unsigned char digest[32]={0};
+	unsigned char digest[HASH_LEN]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
 	unsigned char *buf = (unsigned char *)target_get_scratch_address();
 	uint32_t bytes_to_read;
 	uint32_t block_num = 0;
+	uint32_t total_num_blocks = ((size - 1) / MDTP_FWLOCK_BLOCK_SIZE) + 1;
+	uint32_t rand_int;
+	uint32_t block_size = mmc_get_device_blocksize();
 
-	dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %u\n", name, size);
+	dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %llu\n", name, size);
 
 	ASSERT(name != NULL);
 	ASSERT(hash_table != NULL);
+	ASSERT(size > 0);
+	ASSERT(force_verify_block != NULL);
 
 	index = partition_get_index(name);
 	ptn = partition_get_offset(index);
@@ -231,13 +249,24 @@
 
 	/* initiating parameters for hash calculation using HW crypto */
 	target_crypto_init_params();
+	if (check_aboot_addr_range_overlap((uint32_t)buf, ROUNDUP(MDTP_FWLOCK_BLOCK_SIZE, block_size)))
+	{
+		dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: image buffer address overlaps with aboot addresses.\n", name);
+		return -1;
+	}
 
 	while (MDTP_FWLOCK_BLOCK_SIZE * block_num < size)
 	{
 		if (*force_verify_block == 0)
 		{
+			if(scm_random((uint32_t *)&rand_int, sizeof(rand_int)))
+			{
+				dprintf(CRITICAL,"mdtp: scm_call for random failed\n");
+				return -1;
+			}
+
 			/* Skip validation of this block with probability of verify_num_blocks / total_num_blocks */
-			if ((rand() % total_num_blocks) >= verify_num_blocks)
+			if ((rand_int % total_num_blocks) >= verify_num_blocks)
 			{
 				block_num++;
 				hash_table += 1;
@@ -255,16 +284,16 @@
 			bytes_to_read = MDTP_FWLOCK_BLOCK_SIZE;
 		}
 
-		if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, bytes_to_read))
+		if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, ROUNDUP(bytes_to_read, block_size)))
 		{
 			dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: mmc_read() fail.\n", name);
 			return -1;
 		}
 
 		/* calculating the hash value using HW */
-		hash_find(buf, bytes_to_read, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
+		hash_find(buf, bytes_to_read, digest, CRYPTO_AUTH_ALG_SHA256);
 
-		if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
+		if (memcmp(digest, hash_table->hash, HASH_LEN))
 		{
 			dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: Failed partition hash[%d] verification\n", name, block_num);
 			return -1;
@@ -280,42 +309,80 @@
 	return 0;
 }
 
-/* Verify a given partitinon */
-static int verify_partition(char *name,
-						uint32_t size,
+/* Validate the partition parameters read from DIP */
+static int validate_partition_params(uint64_t size,
 						mdtp_fwlock_mode_t hash_mode,
-						uint32_t total_num_blocks,
-						uint32_t verify_num_blocks,
-						DIP_hash_table_entry_t *hash_table,
-						uint8_t *force_verify_block)
+						uint32_t verify_ratio)
 {
-
-	ASSERT(name != NULL);
-	ASSERT(hash_table != NULL);
-
-	if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
+	if (size == 0 || size > (uint64_t)MDTP_FWLOCK_BLOCK_SIZE * (uint64_t)MAX_BLOCKS ||
+		hash_mode >= MDTP_FWLOCK_MODE_SIZE || verify_ratio > 100)
 	{
-		return verify_partition_single_hash(name, size, hash_table);
-	} else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
-	{
-		return verify_partition_block_hash(name, size, total_num_blocks, verify_num_blocks, hash_table, force_verify_block);
-	}
-	else
-	{
-		dprintf(CRITICAL, "mdtp: verify_partition: %s: Wrong DIP partition hash mode\n", name);
+		dprintf(CRITICAL, "mdtp: validate_partition_params: error, size=%llu, hash_mode=%d, verify_ratio=%d\n",
+			size, hash_mode, verify_ratio);
 		return -1;
 	}
 
 	return 0;
 }
 
+/* Verify a given partitinon */
+static int verify_partition(char *name,
+						uint64_t size,
+						mdtp_fwlock_mode_t hash_mode,
+						uint32_t verify_num_blocks,
+						DIP_hash_table_entry_t *hash_table,
+						uint8_t *force_verify_block)
+{
+	if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
+	{
+		return verify_partition_single_hash(name, size, hash_table);
+	} else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
+	{
+		return verify_partition_block_hash(name, size, verify_num_blocks, hash_table, force_verify_block);
+	}
+
+	/* Illegal value of hash_mode */
+	return -1;
+}
+
+static int validate_dip(DIP_t *dip)
+{
+	uint8_t *dip_p;
+
+	ASSERT(dip != NULL);
+
+	/* Make sure DIP version is supported by current SW */
+	if (MDTP_GET_MAJOR_VERSION(dip->version) != MDTP_MAJOR_VERSION)
+	{
+		dprintf(CRITICAL, "mdtp: validate_dip: Wrong DIP version 0x%x\n", dip->version);
+		return -1;
+	}
+
+	/* Make sure that deactivated DIP content is as expected */
+	if (dip->status == DIP_STATUS_DEACTIVATED)
+	{
+		dip_p = (uint8_t*)&dip->mdtp_cfg;
+		while (dip_p < dip->hash)
+		{
+			if (*dip_p != 0)
+			{
+				dprintf(CRITICAL, "mdtp: validate_dip: error in deactivated DIP\n");
+				return -1;
+			}
+			dip_p++;
+		}
+	}
+
+	return 0;
+}
+
 /* Display the recovery UI to allow the user to enter the PIN and continue boot */
-static int display_recovery_ui(DIP_t *dip)
+static void display_recovery_ui(DIP_t *dip)
 {
 	uint32_t pin_length = 0;
 	char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
 	uint32_t i;
-	uint32_t equal_count = 0, different_count = 0;
+	char pin_mismatch = 0;
 
 	if (dip->mdtp_cfg.enable_local_pin_authentication)
 	{
@@ -326,8 +393,7 @@
 		if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
 		{
 			dprintf(CRITICAL, "mdtp: display_recovery_ui: Error, invalid PIN length\n");
-			display_error_msg();
-			return -1;
+			display_error_msg(); /* This will never return */
 		}
 
 		// Set entered_pin to initial '0' string + null terminator
@@ -340,49 +406,44 @@
 		// (with INVALID_PIN_DELAY_MSECONDS after each failed attempt)
 		while (1)
 		{
-		    get_pin_from_user(entered_pin, pin_length);
+			get_pin_from_user(entered_pin, pin_length);
 
-		    // Go over the entire PIN in any case, to prevent side-channel attacks
-		    for (i=0; i<pin_length; i++)
-		    {
-		        if (dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] == entered_pin[i])
-		            equal_count++;
-		        else
-		            different_count++;
-		    }
+			// Go over the entire PIN in any case, to prevent side-channel attacks
+			for (i=0; i<pin_length; i++)
+			{
+				pin_mismatch |= dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] ^ entered_pin[i];
+			}
 
-		    if (equal_count == pin_length)
-		    {
-		        // Valid PIN - deactivate and continue boot
-		        dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
-		        write_deactivated_DIP();
-		        return 0;
-		    }
-		    else
-		    {
-		        // Invalid PIN - display an appropriate message (which also includes a wait
-		        // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
-		        dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
-		        display_invalid_pin_msg();
+			if (0 == pin_mismatch)
+			{
+				// Valid PIN - deactivate and continue boot
+				dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
+				write_deactivated_DIP();
+				return;
+			}
+			else
+			{
+				// Invalid PIN - display an appropriate message (which also includes a wait
+				// for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
+				dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
+				display_invalid_pin_msg();
 
-		        equal_count = 0;
-		        different_count = 0;
-		    }
+				pin_mismatch = 0;
+			}
 		}
 	}
 	else
 	{
 		dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
-		display_error_msg();
-		return -1;
+		display_error_msg(); /* This will never return */
 	}
 }
 
 /* Verify all protected partitinons according to the DIP */
-static int verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
+static void verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
 {
 	int i;
-	int verify_failure = 0;
+	bool verify_failure = FALSE;
 	uint32_t total_num_blocks;
 
 	ASSERT(dip != NULL);
@@ -390,40 +451,53 @@
 
 	*verify_result = VERIFY_FAILED;
 
+	if (validate_dip(dip))
+	{
+		dprintf(CRITICAL, "mdtp: verify_all_partitions: failed DIP validation\n");
+		return;
+	}
+
 	if (dip->status == DIP_STATUS_DEACTIVATED)
 	{
 		*verify_result = VERIFY_SKIPPED;
-		return 0;
+		return;
 	}
-	else if (dip->status == DIP_STATUS_ACTIVATED)
+	else
 	{
 		for(i=0; i<MAX_PARTITIONS; i++)
 		{
 			if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
 			{
 				total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
+				if (validate_partition_params(dip->partition_cfg[i].size,
+					dip->partition_cfg[i].hash_mode,
+					dip->partition_cfg[i].verify_ratio))
+				{
+					dprintf(CRITICAL, "mdtp: verify_all_partitions: Wrong partition parameters\n");
+					verify_failure = TRUE;
+					break;
+				}
 
-				verify_failure |= verify_partition(dip->partition_cfg[i].name,
+				verify_failure |= (verify_partition(dip->partition_cfg[i].name,
 							 dip->partition_cfg[i].size,
 							 dip->partition_cfg[i].hash_mode,
-							 total_num_blocks,
 							 (dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
 							 dip->partition_cfg[i].hash_table,
-							 dip->partition_cfg[i].force_verify_block);
+							 dip->partition_cfg[i].force_verify_block) != 0);
 			}
 		}
 
 		if (verify_failure)
 		{
 			dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
-			return 0;
+			return;
 		}
 		is_mdtp_activated = 1;
 
 	}
 
 	*verify_result = VERIFY_OK;
-	return 0;
+	return;
 }
 
 /* Verify the DIP and all protected partitions */
@@ -440,7 +514,7 @@
 	if (enc_dip == NULL)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
-		return;
+		display_error_msg(); /* This will never return */
 	}
 
 	dec_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
@@ -448,7 +522,7 @@
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
 		free(enc_dip);
-		return;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Read the DIP holding the MDTP Firmware Lock state from the DIP partition */
@@ -456,7 +530,7 @@
 	if(ret < 0)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot read DIP\n");
-		goto out;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Decrypt and verify the integrity of the DIP */
@@ -464,40 +538,35 @@
 	if(ret < 0)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify DIP\n");
-		display_error_msg();
-		goto out;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* In case DIP integrity verification fails, notify the user and halt */
 	if(!verified)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted DIP\n");
-		display_error_msg();
-		goto out;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Verify the integrity of the partitions which are protectedm, according to the content of the DIP */
-	ret = verify_all_partitions(dec_dip, &verify_result);
-	if(ret < 0)
-	{
-		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify firmware\n");
-		goto out;
-	}
+	verify_all_partitions(dec_dip, &verify_result);
+
+	/* Clear decrypted DIP since we don't need it anymore */
+	memset(dec_dip, 0, sizeof(DIP_t));
 
 	if (verify_result == VERIFY_OK)
 	{
 		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
 	}
-	else if (verify_result  == VERIFY_FAILED)
+	else if (verify_result  == VERIFY_SKIPPED)
+	{
+		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
+	} else /* VERIFY_FAILED */
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
 		display_recovery_ui(dec_dip);
-	} else /* VERIFY_SKIPPED */
-	{
-		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
 	}
 
-out:
 	free(enc_dip);
 	free(dec_dip);
 
@@ -509,7 +578,7 @@
 /** Entry point of the MDTP Firmware Lock: If needed, verify the DIP
  *  and all protected partitions **/
 
-int mdtp_fwlock_verify_lock()
+void mdtp_fwlock_verify_lock()
 {
 	int ret;
 	bool enabled;
@@ -521,16 +590,15 @@
 	if(ret)
 	{
 		dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
-		return -1;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Continue with Firmware Lock verification only if enabled by eFuse */
 	if (enabled)
 	{
+		/* This function will handle firmware verification failure via UI */
 		validate_DIP_and_firmware();
 	}
-
-	return 0;
 }
 /********************************************************************************/
 
@@ -550,7 +618,6 @@
 /* Decrypt a given DIP and verify its integrity */
 static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified)
 {
-	unsigned char *hash_p;
 	unsigned char hash[HASH_LEN];
 	SHA256_CTX sha256_ctx;
 	int ret;
@@ -566,6 +633,7 @@
 	{
 		dprintf(CRITICAL, "mdtp: mdtp_tzbsp_dec_verify_DIP: ERROR, cannot cipher DIP\n");
 		*verified = 0;
+		memset(dec_dip, 0, sizeof(DIP_t));
 		return -1;
 	}
 
@@ -573,11 +641,10 @@
 	SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
 	SHA256_Final(hash, &sha256_ctx);
 
-	hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
-
-	if (memcmp(hash, hash_p, HASH_LEN))
+	if (memcmp(hash, dec_dip->hash, HASH_LEN))
 	{
 		*verified = 0;
+		memset(dec_dip, 0, sizeof(DIP_t));
 	}
 	else
 	{
@@ -589,18 +656,15 @@
 
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
 {
-	unsigned char *hash_p;
 	SHA256_CTX sha256_ctx;
 	int ret;
 
 	ASSERT(dec_dip != NULL);
 	ASSERT(enc_dip != NULL);
 
-	hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
-
 	SHA256_Init(&sha256_ctx);
 	SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
-	SHA256_Final(hash_p, &sha256_ctx);
+	SHA256_Final(dec_dip->hash, &sha256_ctx);
 
 	ret = mdtp_cipher_dip_cmd((uint8_t*)dec_dip, sizeof(DIP_t),
 								(uint8_t*)enc_dip, sizeof(DIP_t),
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index 865c791..0f30b54 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -29,21 +29,21 @@
 #ifndef __APP_MDTP_H
 #define __APP_MDTP_H
 
-#define TOKEN_LEN 16
-#define MAX_BLOCKS 512
-#define MAX_PARTITIONS 3
-#define MAX_PARTITION_NAME_LEN 100
-#define HASH_LEN 32
-#define MDTP_MIN_PIN_LEN 5
-#define MDTP_MAX_PIN_LEN 8
-#define DIP_PADDING 11
+#define TOKEN_LEN              (16)
+#define MAX_BLOCKS             (512)
+#define MAX_PARTITIONS         (3)
+#define MAX_PARTITION_NAME_LEN (100)
+#define HASH_LEN               (32)
+#define MDTP_MAX_PIN_LEN       (8)
+#define MDTP_MIN_PIN_LEN       (5)
+#define DIP_PADDING            (15)
 
 #define INITIAL_DELAY_MSECONDS      5000
 #define INVALID_PIN_DELAY_MSECONDS  5000
 
 #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
-#define MDTP_FWLOCK_BLOCK_SIZE (1024*1024*16)
-#define MDTP_FWLOCK_MAX_FILES (100)
+#define MDTP_FWLOCK_BLOCK_SIZE          (1024*1024*16)
+#define MDTP_FWLOCK_MAX_FILES           (100)
 #define MDTP_FWLOCK_MAX_FILE_NAME_LEN   (100)
 
 #pragma pack(push, mdtp, 1)
@@ -66,7 +66,7 @@
 } DIP_hash_table_entry_t;
 
 typedef struct DIP_partition_cfg {
-	uint32_t size;                                  /* DIP size */
+	uint64_t size;                                  /* Partition size in bytes */
 	char name[MAX_PARTITION_NAME_LEN];              /* Partition name */
 	uint8_t lock_enabled;                           /* Image locked? */
 	mdtp_fwlock_mode_t hash_mode;                   /* Hash per IMAGE or BLOCK */
@@ -114,9 +114,9 @@
  *
  * Start Firmware Lock verification process.
  *
- * @return - negative value for an error, 0 for success.
+ * @return - None.
  */
-int mdtp_fwlock_verify_lock();
+void mdtp_fwlock_verify_lock();
 
 /**
  * mdtp_fuse_get_enabled
diff --git a/app/aboot/mdtp_fuse.c b/app/aboot/mdtp_fuse.c
index 1487057..239d263 100644
--- a/app/aboot/mdtp_fuse.c
+++ b/app/aboot/mdtp_fuse.c
@@ -36,8 +36,6 @@
 #include "mdtp.h"
 #include "scm.h"
 
-#define MAX_EFUSES              (8)
-#define EFUSE_END               (MDTP_EFUSE_START + MAX_EFUSES - 1)
 #define MAX_METADATA_SIZE       (0x1000)
 #define QFPROM_ADDR_SPACE_RAW   (0)
 
@@ -228,7 +226,7 @@
  * Read the Firmware Lock eFuses and return whether the Firmware
  * Lock is currently enabled or disabled in HW.
  *
- * @param[out] enabled: 0 - enable, 1 - disable.
+ * @param[out] enabled: 0 - disabled, 1 - enabled.
  *
  * @return - negative value for an error, 0 for success.
  */
@@ -237,6 +235,8 @@
 	int status;
 	mdtp_eFuses_t eFuses;
 
+	*enabled = 1;
+
 	status = read_fuse(&eFuses.mask);
 	if (status)
 	{
@@ -244,14 +244,12 @@
 		return -1;
 	}
 
-	if ((eFuses.bitwise.enable1 && !eFuses.bitwise.disable1) ||
-		(eFuses.bitwise.enable2 && !eFuses.bitwise.disable2) ||
-		(eFuses.bitwise.enable3 && !eFuses.bitwise.disable3))
+	if (!(eFuses.bitwise.enable1 && !eFuses.bitwise.disable1) &&
+		!(eFuses.bitwise.enable2 && !eFuses.bitwise.disable2) &&
+		!(eFuses.bitwise.enable3 && !eFuses.bitwise.disable3))
 	{
-		*enabled = 1;
-	}
-	else
 		*enabled = 0;
+	}
 
 	return 0;
 }
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 48d899e..7a94ad6 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -78,7 +78,7 @@
 #define BITS_PER_BYTE                       (8)
 
 
-#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width)         ((screen_width-image_width)/2)
+#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width)         (((screen_width)-(image_width))/2)
 
 extern void mdelay(unsigned msecs);
 extern uint32_t target_volume_up();
@@ -131,8 +131,9 @@
 	if (fb_config)
 	{
 		uint8_t *base = logo->image;
+		unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
 
-		if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*3, block_size))) {
+		if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
 				fbcon_clear();
 				dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
 				return NULL;
@@ -180,7 +181,7 @@
 	else
 	{
 	    dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
-	    display_error_msg();
+	    display_error_msg(); /* This will never return */
 	}
 }
 
@@ -218,11 +219,15 @@
 	if (bytes_per_bpp == 3)
 	{
 		if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
-			return;
-
-		if (fbimg->width > fb_config->width || fbimg->height > fb_config->height)
 		{
-		    dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen\n");
+			dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
+			return;
+		}
+
+		if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
+				 (x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
+		{
+		    dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
 		    return;
 		}
 
@@ -232,6 +237,11 @@
 				logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
 		}
 	}
+	else
+	{
+		dprintf(CRITICAL,"ERROR: invalid bpp value\n");
+		display_error_msg(); /* This will never return */
+	}
 
 	fbcon_flush();
 
@@ -240,17 +250,6 @@
         mipi_dsi_cmd_mode_trigger();
 #endif
 
-#else
-    if (bytes_per_bpp == 2)
-    {
-        for (i = 0; i < fbimg->width; i++)
-        {
-            memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
-		   fbimg->image + (i * fbimg->height * bytes_per_bpp),
-		   fbimg->height * bytes_per_bpp);
-        }
-    }
-    fbcon_flush();
 #endif
 }
 
@@ -261,8 +260,6 @@
 {
     struct mdtp_fbimage *fbimg;
 
-    fb_config = fbcon_display();
-
     if (fb_config)
 	{
         uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_ERROR_MSG_WIDTH,fb_config->width);
@@ -300,7 +297,7 @@
         if (NULL == fbimg)
         {
             dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
-            display_error_msg();
+            display_error_msg(); /* This will never return */
         }
 
         fbcon_putImage_in_location(fbimg, x, y);
@@ -308,7 +305,7 @@
     else
     {
         dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
-        display_error_msg();
+        display_error_msg(); /* This will never return */
     }
 }
 
@@ -442,7 +439,7 @@
 		fbcon_clear();
 
 		if (display_error_message())
-		    display_error_msg();
+		    display_error_msg(); /* This will never return */
 		display_initial_delay();
 
 		mdelay(INITIAL_DELAY_MSECONDS);
@@ -452,12 +449,12 @@
 		uint32_t total_pin_length = pin_length*MDTP_PIN_DIGIT_WIDTH + DIGIT_SPACE*(pin_length - 1);
 		uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
 
-		for (int i=0; i<(int)pin_length; i++)
+		for (uint32_t i=0; i<pin_length; i++)
 		{
 			g_pin_frames_x_location[i] = complete_pin_centered + i*(DIGIT_SPACE+MDTP_PIN_DIGIT_WIDTH);
 		}
 
-		for (int i=0; i<(int)pin_length; i++)
+		for (uint32_t i=0; i<pin_length; i++)
 		{
 			display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
 		}
@@ -469,8 +466,7 @@
 	else
 	{
 	    dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
-	    display_error_msg();
-		return;
+	    display_error_msg(); /* This will never return */
 	}
 }
 
@@ -588,15 +584,17 @@
  */
 void display_error_msg()
 {
-    fbcon_clear();
-	display_error_message();   // No point in checking the return value here
+	fb_config = fbcon_display();
+
+	if (fb_config)
+	{
+		fbcon_clear();
+		display_error_message();   // No point in checking the return value here
+	}
 
 	// Invalid state. Nothing to be done but contacting the OEM.
 	// Stop boot process.
 	dprintf(CRITICAL,"ERROR: blocking boot process\n");
-	while(1)
-	{
-
-	}
+	for(;;);
 }
 
diff --git a/arch/arm/rules.mk b/arch/arm/rules.mk
index a4bf38c..f45a6eb 100644
--- a/arch/arm/rules.mk
+++ b/arch/arm/rules.mk
@@ -132,23 +132,24 @@
 
 
 
-$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%ROMLITE_PREFLASHED_DATA%/$(ROMLITE_PREFLASHED_DATA)/" < $< > $@
 
-$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
 
-$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
 
-$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
 
+.FORCE:
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
old mode 100755
new mode 100644
index 066fd13..ccc47cd
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -64,16 +64,18 @@
 
 static uint32_t panel_backlight_ctrl(uint8_t enable)
 {
-	return target_backlight_ctrl(panelstruct.backlightinfo, enable);
+	uint32_t ret = NO_ERROR;
+	if (panelstruct.backlightinfo)
+		ret = target_backlight_ctrl(panelstruct.backlightinfo, enable);
+	return ret;
 }
 
 static uint32_t mdss_dsi_panel_reset(uint8_t enable)
 {
 	uint32_t ret = NO_ERROR;
-
-	ret = target_panel_reset(enable, panelstruct.panelresetseq,
-						&panel.panel_info);
-
+	if (panelstruct.panelresetseq)
+		ret = target_panel_reset(enable, panelstruct.panelresetseq,
+							&panel.panel_info);
 	return ret;
 }
 
@@ -422,7 +424,8 @@
 	arg_size = prefix_string_len + dsi_id_len + panel_node_len +
 						LK_OVERRIDE_PANEL_LEN + 1;
 
-	if (!strcmp(panelstruct.paneldata->panel_destination, "DISPLAY_2"))
+	if (panelstruct.paneldata &&
+		!strcmp(panelstruct.paneldata->panel_destination, "DISPLAY_2"))
 		sctl_string = DSI_0_STRING;
 	else
 		sctl_string = DSI_1_STRING;
@@ -458,22 +461,6 @@
 	return ret;
 }
 
-
-static void init_platform_data()
-{
-	if (dsi_video_mode_phy_db.pll_type == DSI_PLL_TYPE_THULIUM)
-		return;
-
-	memcpy(dsi_video_mode_phy_db.regulator, panel_regulator_settings,
-							REGULATOR_SIZE);
-	memcpy(dsi_video_mode_phy_db.ctrl, panel_physical_ctrl,
-							PHYSICAL_SIZE);
-	memcpy(dsi_video_mode_phy_db.strength, panel_strength_ctrl,
-							STRENGTH_SIZE);
-	memcpy(dsi_video_mode_phy_db.bistCtrl, panel_bist_ctrl, BIST_SIZE);
-	memcpy(dsi_video_mode_phy_db.laneCfg, panel_lane_config, LANE_SIZE);
-}
-
 static void mdss_edp_panel_init(struct msm_panel_info *pinfo)
 {
 	return target_edp_panel_init(pinfo);
@@ -543,6 +530,11 @@
 	return ret;
 }
 
+static int mdss_dsi2HDMI_config (struct msm_panel_info *pinfo)
+{
+	return target_display_dsi2hdmi_config(pinfo);
+}
+
 int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
 {
 	int ret = NO_ERROR;
@@ -553,7 +545,7 @@
 				 &dsi_video_mode_phy_db);
 
 	if (pan_type == PANEL_TYPE_DSI) {
-		init_platform_data();
+		target_dsi_phy_config(&dsi_video_mode_phy_db);
 		if (dsi_panel_init(&(panel.panel_info), &panelstruct)) {
 			dprintf(CRITICAL, "DSI panel init failed!\n");
 			ret = ERROR;
@@ -566,6 +558,7 @@
 		panel.power_func = mdss_dsi_panel_power;
 		panel.pre_init_func = mdss_dsi_panel_pre_init;
 		panel.bl_func = mdss_dsi_bl_enable;
+		panel.dsi2HDMI_config = mdss_dsi2HDMI_config;
 		/*
 		 * If dfps enabled, reserve fb memory to store pll
 		 * codes and pass pll codes values to kernel.
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index 0d6f06f..d1f1df5 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -52,6 +52,8 @@
 int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
 						struct msm_panel_info *pinfo);
 int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo);
+int target_display_dsi2hdmi_config(struct msm_panel_info *pinfo);
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db);
 
 int gcdb_display_init(const char *panel_name, uint32_t rev, void *base);
 int gcdb_display_cmdline_arg(char *panel_name, char *pbuf, uint16_t buf_size);
diff --git a/dev/gcdb/display/include/panel.h b/dev/gcdb/display/include/panel.h
index 913bafb..f75850c 100755
--- a/dev/gcdb/display/include/panel.h
+++ b/dev/gcdb/display/include/panel.h
@@ -38,6 +38,9 @@
 
 #define TOTAL_RESET_GPIO_CTRL 5
 
+#define ADV7533_MAIN    (0x39)
+#define ADV7533_CEC_DSI (0x3c)
+
 /*---------------------------------------------------------------------------*/
 /* panel type 								     */
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_adv7533_1080p60.h b/dev/gcdb/display/include/panel_adv7533_1080p60.h
new file mode 100755
index 0000000..ceba5ce
--- /dev/null
+++ b/dev/gcdb/display/include/panel_adv7533_1080p60.h
@@ -0,0 +1,177 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PANEL_ADV7533_1080p60_H_
+#define _PANEL_ADV7533_1080p60_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config adv7533_1080p_video_panel_data = {
+	"qcom,mdss_dsi_adv7533_1080p60_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution adv7533_1080p_video_panel_res = {
+	1920, 1080, 88, 148, 44, 0, 4, 36, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info adv7533_1080p_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+static struct mipi_dsi_i2c_cmd adv7533_1080p_common_cfg[] = {
+	{ADV7533_MAIN, 0xd6, 0x48, 5},		/* HPD overriden */
+	{ADV7533_MAIN, 0x41, 0x10, 5},		/* HDMI normal */
+	{ADV7533_CEC_DSI, 0x03, 0x89, 0},	/* HDMI enabled */
+	{ADV7533_MAIN, 0x16, 0x20, 0},
+	{ADV7533_MAIN, 0x9A, 0xE0, 0},
+	{ADV7533_MAIN, 0xBA, 0x70, 0},
+	{ADV7533_MAIN, 0xDE, 0x82, 0},
+	{ADV7533_MAIN, 0xE4, 0x40, 0},
+	{ADV7533_MAIN, 0xE5, 0x80, 0},
+	{ADV7533_CEC_DSI, 0x15, 0xD0, 0},
+	{ADV7533_CEC_DSI, 0x17, 0xD0, 0},
+	{ADV7533_CEC_DSI, 0x24, 0x20, 0},
+	{ADV7533_CEC_DSI, 0x57, 0x11, 0},
+	/* hdmi or dvi mode: hdmi */
+	{ADV7533_MAIN, 0xAF, 0x06, 0},
+	{ADV7533_MAIN, 0x40, 0x80, 0},
+	{ADV7533_MAIN, 0x4C, 0x04, 0},
+	{ADV7533_MAIN, 0x49, 0x02, 0},
+	{ADV7533_MAIN, 0x0D, 1 << 6, 0},
+	{ADV7533_CEC_DSI, 0x1C, 0x30, 0},
+};
+
+#define ADV7533_1080P_CONFIG_COMMANDS 19
+
+static struct mipi_dsi_i2c_cmd adv7533_1080p_tg_i2c_command[] = {
+	/*4 Lanes*/
+	{ADV7533_CEC_DSI, 0x1C, 0x40},
+	/* hsync and vsync active low */
+	{ADV7533_MAIN, 0x17, 0x02},
+	/* Control for Pixel Clock Divider */
+	{ADV7533_CEC_DSI, 0x16, 0x00},
+	/* Timing Generator Enable */
+	{ADV7533_CEC_DSI, 0x27, 0xCB},
+	/* h_width 0x898 2200*/
+	{ADV7533_CEC_DSI, 0x28, 0x89},
+	{ADV7533_CEC_DSI, 0x29, 0x80},
+	/* hsync_width 0x2c 44*/
+	{ADV7533_CEC_DSI, 0x2A, 0x02},
+	{ADV7533_CEC_DSI, 0x2B, 0xC0},
+	/* hfp 0x58 88 */
+	{ADV7533_CEC_DSI, 0x2C, 0x05},
+	{ADV7533_CEC_DSI, 0x2D, 0x80},
+	/* hbp 0x94 148 */
+	{ADV7533_CEC_DSI, 0x2E, 0x09},
+	{ADV7533_CEC_DSI, 0x2F, 0x40},
+	/* v_total 0x465 1125*/
+	{ADV7533_CEC_DSI, 0x30, 0x46},
+	{ADV7533_CEC_DSI, 0x31, 0x50},
+	/* vsync_width 0x05 5*/
+	{ADV7533_CEC_DSI, 0x32, 0x00},
+	{ADV7533_CEC_DSI, 0x33, 0x50},
+	/* vfp 0x04 4  */
+	{ADV7533_CEC_DSI, 0x34, 0x00},
+	{ADV7533_CEC_DSI, 0x35, 0x40},
+	/* vbp 0x24 36 */
+	{ADV7533_CEC_DSI, 0x36, 0x02},
+	{ADV7533_CEC_DSI, 0x37, 0x40},
+	/* Timing Generator Enable */
+	{ADV7533_CEC_DSI, 0x27, 0xCB},
+	{ADV7533_CEC_DSI, 0x27, 0x8B},
+	{ADV7533_CEC_DSI, 0x27, 0xCB},
+	/* Reset Internal Timing Generator */
+	{ADV7533_MAIN, 0xAF, 0x16},
+	/* HDMI Mode Select */
+	{ADV7533_CEC_DSI, 0x03, 0x89},
+	/* HDMI Output Enable */
+	{ADV7533_MAIN, 0x40, 0x80},
+	/* GC Packet Enable */
+	{ADV7533_MAIN, 0x4C, 0x04},
+	/* Colour Depth 24-bit per pixel */
+	{ADV7533_MAIN, 0x49, 0x00},
+	/* Down Dither Output 8-bit Colour Depth */
+	{ADV7533_CEC_DSI, 0x05, 0xF8},
+	/* ADI Required Write */
+	{ADV7533_CEC_DSI, 0xBE, 0x3D},
+	/* Test Pattern Disable (0x55[7] = 0) */
+	{ADV7533_CEC_DSI, 0x55, 0x00},
+};
+
+#define ADV7533_1080P_TG_COMMANDS 31
+
+static struct command_state adv7533_1080p_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info adv7533_1080p_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info adv7533_1080p_video_video_panel = {
+	1, 0, 0, 0, 1, 1, 0, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration adv7533_1080p_video_lane_config = {
+	4, 0, 1, 1, 1, 1, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t adv7533_1080p_video_timings[] = {
+	0xa9, 0x4A, 0x32, 0x00, 0x82, 0x86, 0x38, 0x4e, 0x3d, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing adv7533_1080p_video_timing_info = {
+	0x0, 0x04, 0x01, 0x27
+};
+
+#endif /*_PANEL_ADV7533_1080p60_H_*/
+
diff --git a/dev/gcdb/display/include/panel_adv7533_720p60.h b/dev/gcdb/display/include/panel_adv7533_720p60.h
new file mode 100644
index 0000000..c56971f
--- /dev/null
+++ b/dev/gcdb/display/include/panel_adv7533_720p60.h
@@ -0,0 +1,162 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _PANEL_ADV7533_720p60_H_
+#define _PANEL_ADV7533_720p60_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config adv7533_720p_video_panel_data = {
+	"qcom,mdss_dsi_adv7533_720p60_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution adv7533_720p_video_panel_res = {
+	1280, 720, 110, 220, 40, 0, 5, 20, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info adv7533_720p_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+static struct mipi_dsi_i2c_cmd adv7533_720p_common_cfg[] = {
+	{ADV7533_MAIN, 0xd6, 0x48, 5},		/* HPD overriden */
+	{ADV7533_MAIN, 0x41, 0x10, 5},		/* HDMI normal */
+	{ADV7533_CEC_DSI, 0x03, 0x89, 0},	/* HDMI enabled */
+	{ADV7533_MAIN, 0x16, 0x20, 0},
+	{ADV7533_MAIN, 0x9A, 0xE0, 0},
+	{ADV7533_MAIN, 0xBA, 0x70, 0},
+	{ADV7533_MAIN, 0xDE, 0x82, 0},
+	{ADV7533_MAIN, 0xE4, 0xC0, 0},
+	{ADV7533_MAIN, 0xE5, 0x80, 0},
+	{ADV7533_CEC_DSI, 0x15, 0xD0, 0},
+	{ADV7533_CEC_DSI, 0x17, 0xD0, 0},
+	{ADV7533_CEC_DSI, 0x24, 0x20, 0},
+	{ADV7533_CEC_DSI, 0x57, 0x11, 0},
+	/* hdmi or dvi mode: hdmi */
+	{ADV7533_MAIN, 0xAF, 0x06, 0},
+	{ADV7533_MAIN, 0x40, 0x80, 0},
+	{ADV7533_MAIN, 0x4C, 0x04, 0},
+	{ADV7533_MAIN, 0x49, 0x02, 0},
+	{ADV7533_MAIN, 0x0D, 1 << 6, 0},
+	{ADV7533_CEC_DSI, 0x1C, 0x30, 0},
+};
+
+#define ADV7533_720P_CONFIG_COMMANDS 19
+
+static struct mipi_dsi_i2c_cmd adv7533_720p_tg_i2c_command[] = {
+	/*3 Lanes*/
+	{ADV7533_CEC_DSI, 0x1C, 0x30},
+	/* hsync and vsync active low */
+	{ADV7533_MAIN, 0x17, 0x02},
+	/* Control for Pixel Clock Divider */
+	{ADV7533_CEC_DSI, 0x16, 0x24},
+	/* h_width 0x672 1650*/
+	{ADV7533_CEC_DSI, 0x28, 0x67},
+	{ADV7533_CEC_DSI, 0x29, 0x20},
+	/* hsync_width 0x28 40*/
+	{ADV7533_CEC_DSI, 0x2A, 0x02},
+	{ADV7533_CEC_DSI, 0x2B, 0x80},
+	/* hfp 0x6E 110 */
+	{ADV7533_CEC_DSI, 0x2C, 0x06},
+	{ADV7533_CEC_DSI, 0x2D, 0xE0},
+	/* hbp 0xDC 220 */
+	{ADV7533_CEC_DSI, 0x2E, 0x0D},
+	{ADV7533_CEC_DSI, 0x2F, 0xC0},
+	/* v_total 0x2EE 750*/
+	{ADV7533_CEC_DSI, 0x30, 0x2E},
+	{ADV7533_CEC_DSI, 0x31, 0xE0},
+	/* vsync_width 0x05 5*/
+	{ADV7533_CEC_DSI, 0x32, 0x00},
+	{ADV7533_CEC_DSI, 0x33, 0x50},
+	/* vfp 0x05 5  */
+	{ADV7533_CEC_DSI, 0x34, 0x00},
+	{ADV7533_CEC_DSI, 0x35, 0x50},
+	/* vbp 0x14 20 */
+	{ADV7533_CEC_DSI, 0x36, 0x01},
+	{ADV7533_CEC_DSI, 0x37, 0x40},
+	/* Test Pattern Disable (0x55[7] = 0) */
+	{ADV7533_CEC_DSI, 0x55, 0x00},
+	/* HDMI disabled */
+	{ADV7533_CEC_DSI, 0x03, 0x09},
+	/* HDMI enabled */
+	{ADV7533_CEC_DSI, 0x03, 0x89},
+};
+
+#define ADV7533_720P_TG_COMMANDS 22
+
+static struct command_state adv7533_720p_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info adv7533_720p_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info adv7533_720p_video_video_panel = {
+	1, 0, 0, 0, 1, 1, 0, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration adv7533_720p_video_lane_config = {
+	3, 0, 1, 1, 1, 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t adv7533_720p_video_timings[] = {
+	0xa4, 0x24, 0x18, 0x00, 0x4e, 0x52, 0x1c, 0x28, 0x1c, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing adv7533_720p_video_timing_info = {
+	0x0, 0x04, 0x03, 0x20
+};
+
+#endif /*_PANEL_ADV7533_720p60_H_*/
+
diff --git a/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h
index 8cfee8e..eedadf6 100644
--- a/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h
@@ -44,9 +44,9 @@
 /* Panel configuration                                                       */
 /*---------------------------------------------------------------------------*/
 static struct panel_config jdi_4k_dualdsi_video_panel_data = {
-	"qcom,dsi_jdi_4k_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+	"qcom,dsi_jdi_4k_video", "dsi:0:", "qcom,mdss-dsi-panel",
 	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
-	"qcom,dsi_jdi_4k_video_1",
+	"qcom,dsi_jdi_4k_video",
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h
index 4c0f3fc..5bc2e91 100644
--- a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h
+++ b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h
@@ -44,9 +44,9 @@
 /* Panel configuration                                                       */
 /*---------------------------------------------------------------------------*/
 static struct panel_config jdi_qhd_dualdsi_cmd_panel_data = {
-	"qcom,mdss_dsi_jdi_qhd_dualmipi0_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+	"qcom,mdss_dsi_jdi_qhd_dualmipi_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
 	10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
-	"qcom,mdss_dsi_jdi_qhd_dualmipi1_cmd"
+	"qcom,mdss_dsi_jdi_qhd_dualmipi_cmd"
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h
index 3ad1e20..a403f31 100644
--- a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h
@@ -44,9 +44,9 @@
 /* Panel configuration                                                       */
 /*---------------------------------------------------------------------------*/
 static struct panel_config jdi_qhd_dualdsi_video_panel_data = {
-	"qcom,dsi_jdi_qhd_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+	"qcom,dsi_jdi_qhd_video", "dsi:0:", "qcom,mdss-dsi-panel",
 	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
-	"qcom,dsi_jdi_qhd_video_1",
+	"qcom,dsi_jdi_qhd_video",
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
new file mode 100644
index 0000000..9714b26
--- /dev/null
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
@@ -0,0 +1,265 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PANEL_NT35597_WQXGA_DUALDSI_VIDEO_H_
+#define _PANEL_NT35597_WQXGA_DUALDSI_VIDEO_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config nt35597_wqxga_dualdsi_video_panel_data = {
+	"qcom,mdss_dsi_nt35597_wqxga_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 25, 1, 0,
+	"qcom,mdss_dsi_nt35597_wqxga_video_1"
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution nt35597_wqxga_dualdsi_video_panel_res = {
+	1440, 2560, 100, 32, 16, 0, 8, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info nt35597_wqxga_dualdsi_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char nt35597_wqxga_dualdsi_video_on_cmd0[] = {
+	0xff, 0x10, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd1[] = {
+	0xfb, 0x01, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd2[] = {
+	0xba, 0x03, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd3[] = {
+	0xe5, 0x01, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd4[] = {
+	0x35, 0x00, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd5[] = {
+	0xbb, 0x03, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd6[] = {
+	0xb0, 0x03, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd7[] = {
+	0x06, 0x0, 0x39, 0xc0,
+	0x3b, 0x03, 0x08, 0x08,
+	0x64, 0x9a, 0xff, 0xff
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd8[] = {
+	0xff, 0xe0, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd9[] = {
+	0xfb, 0x01, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd10[] = {
+	0x6b, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd11[] = {
+	0x6c, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd12[] = {
+	0x6d, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd13[] = {
+	0x6e, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd14[] = {
+	0x6f, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd15[] = {
+	0x35, 0x02, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd16[] = {
+	0x36, 0x72, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd17[] = {
+	0x37, 0x10, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd18[] = {
+	0x8, 0xc0, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd19[] = {
+	0xff, 0x10, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd20[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd21[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd nt35597_wqxga_dualdsi_video_on_command[] = {
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd0, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd1, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd2, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd3, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd4, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd5, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd6, 0x10},
+	{0xc, nt35597_wqxga_dualdsi_video_on_cmd7, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd8, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd9, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd10, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd11, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd12, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd13, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd14, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd15, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd16, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd17, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd18, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd19, 0x10},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd20, 0x78},
+	{0x4, nt35597_wqxga_dualdsi_video_on_cmd21, 0x78},
+};
+
+#define NT35597_WQXGA_DUALDSI_VIDEO_ON_COMMAND 22
+
+
+static char nt35597_wqxga_dualdsi_videooff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_videooff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd nt35597_wqxga_dualdsi_video_off_command[] = {
+	{0x4, nt35597_wqxga_dualdsi_videooff_cmd0, 0x32},
+	{0x4, nt35597_wqxga_dualdsi_videooff_cmd1, 0x78}
+};
+
+#define NT35597_WQXGA_DUALDSI_VIDEO_OFF_COMMAND 2
+
+static struct command_state nt35597_wqxga_dualdsi_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info nt35597_wqxga_dualdsi_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info nt35597_wqxga_dualdsi_video_video_panel = {
+	0, 0, 0, 0, 1, 1, 1, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration nt35597_wqxga_dualdsi_video_lane_config = {
+	4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t nt35597_wqxga_dualdsi_video_timings[] = {
+	0xe2, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x28, 0x38,  0x2a, 0x03, 0x04, 0x00
+};
+
+static const uint32_t nt35597_wqxga_dualdsi_thulium_video_timings[] = {
+	0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+	0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+	0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+	0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+	0x23, 0x2d, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+};
+
+static struct panel_timing nt35597_wqxga_dualdsi_video_timing_info = {
+	0x0, 0x04, 0x02, 0x2a
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence nt35597_wqxga_dualdsi_video_reset_seq = {
+	{1, 0, 1, }, {20, 20, 50, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight nt35597_wqxga_dualdsi_video_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"		/* BL_WLED */
+};
+
+static struct labibb_desc nt35597_wqxga_dualdsi_video_labibb = {
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Dynamic fps supported frequencies by panel                                */
+/*---------------------------------------------------------------------------*/
+static const struct dfps_panel_info nt35597_wqxga_dualdsi_video_dfps = {
+	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
+};
+
+#endif
diff --git a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
index 169e980..ef5bc4c 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
@@ -44,9 +44,9 @@
 /* Panel configuration                                                       */
 /*---------------------------------------------------------------------------*/
 static struct panel_config sharp_wqxga_dualdsi_video_panel_data = {
-	"qcom,mdss_dsi_sharp_wqxga_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+	"qcom,mdss_dsi_sharp_wqxga_video", "dsi:0:", "qcom,mdss-dsi-panel",
 	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 25, 1, 0,
-	"qcom,mdss_dsi_sharp_wqxga_video_1"
+	"qcom,mdss_dsi_sharp_wqxga_video"
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/platform/msm8909/acpuclock.c b/platform/msm8909/acpuclock.c
index b8e0df4..ed2cbfc 100644
--- a/platform/msm8909/acpuclock.c
+++ b/platform/msm8909/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -37,6 +37,8 @@
 #include <platform/clock.h>
 #include <blsp_qup.h>
 
+#define MAX_LOOPS	500
+
 void hsusb_clock_init(void)
 {
 	int ret;
@@ -358,6 +360,34 @@
 	}
 }
 
+static void rcg_update_config(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(0)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(31)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
 /* Disable all the branch clocks needed by the DSI controller */
 void gcc_dsi_clocks_disable(void)
 {
@@ -371,20 +401,32 @@
 {
 	int ret;
 
-	/* Configure Byte clock -autopll- This will not change becasue
-	byte clock does not need any divider*/
+	/*
+	 * Configure Byte clock -autopll- This will not change becasue
+	 * byte clock does not need any divider
+	 */
+	/* Set the source for DSI0 byte RCG */
 	writel(0x100, DSI_BYTE0_CFG_RCGR);
+	/* Set the update RCG bit */
 	writel(0x1, DSI_BYTE0_CMD_RCGR);
+	rcg_update_config(DSI_BYTE0_CMD_RCGR);
+	/* Enable the branch clock */
 	writel(0x1, DSI_BYTE0_CBCR);
+	branch_clk_halt_check(DSI_BYTE0_CBCR);
 
 	/* Configure Pixel clock */
+	/* Set the source for DSI0 pixel RCG */
 	writel(0x100, DSI_PIXEL0_CFG_RCGR);
-	writel(0x1, DSI_PIXEL0_CMD_RCGR);
-	writel(0x1, DSI_PIXEL0_CBCR);
-
+	/* Set the MND for DSI0 pixel clock */
 	writel(pclk0_m, DSI_PIXEL0_M);
 	writel(pclk0_n, DSI_PIXEL0_N);
 	writel(pclk0_d, DSI_PIXEL0_D);
+	/* Set the update RCG bit */
+	writel(0x1, DSI_PIXEL0_CMD_RCGR);
+	rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+	/* Enable the branch clock */
+	writel(0x1, DSI_PIXEL0_CBCR);
+	branch_clk_halt_check(DSI_PIXEL0_CBCR);
 
 	/* Configure ESC clock */
 	ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
diff --git a/platform/msm8916/acpuclock.c b/platform/msm8916/acpuclock.c
index fd365be..158ab39 100644
--- a/platform/msm8916/acpuclock.c
+++ b/platform/msm8916/acpuclock.c
@@ -38,6 +38,8 @@
 #include <blsp_qup.h>
 #include <platform.h>
 
+#define MAX_LOOPS	500
+
 void hsusb_clock_init(void)
 {
 	int ret;
@@ -262,6 +264,34 @@
 	}
 }
 
+static void rcg_update_config(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(0)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(31)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
 /* Disable all the branch clocks needed by the DSI controller */
 void gcc_dsi_clocks_disable(uint8_t dual_dsi)
 {
@@ -280,20 +310,32 @@
 {
 	int ret;
 
-	/* Configure Byte clock -autopll- This will not change becasue
-	byte clock does not need any divider*/
+	/*
+	 * Configure Byte clock -autopll- This will not change becasue
+	 * byte clock does not need any divider
+	 */
+	/* Set the source for DSI0 byte RCG */
 	writel(0x100, DSI_BYTE0_CFG_RCGR);
+	/* Set the update RCG bit */
 	writel(0x1, DSI_BYTE0_CMD_RCGR);
+	rcg_update_config(DSI_BYTE0_CMD_RCGR);
+	/* Enable the branch clock */
 	writel(0x1, DSI_BYTE0_CBCR);
+	branch_clk_halt_check(DSI_BYTE0_CBCR);
 
 	/* Configure Pixel clock */
+	/* Set the source for DSI0 pixel RCG */
 	writel(0x100, DSI_PIXEL0_CFG_RCGR);
-	writel(0x1, DSI_PIXEL0_CMD_RCGR);
-	writel(0x1, DSI_PIXEL0_CBCR);
-
+	/* Set the MND for DSI0 pixel clock */
 	writel(pclk0_m, DSI_PIXEL0_M);
 	writel(pclk0_n, DSI_PIXEL0_N);
 	writel(pclk0_d, DSI_PIXEL0_D);
+	/* Set the update RCG bit */
+	writel(0x1, DSI_PIXEL0_CMD_RCGR);
+	rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+	/* Enable the branch clock */
+	writel(0x1, DSI_PIXEL0_CBCR);
+	branch_clk_halt_check(DSI_PIXEL0_CBCR);
 
 	/* Configure ESC clock */
 	ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
@@ -303,20 +345,27 @@
 	}
 
 	if (dual_dsi) {
-		/* Configure Byte clock -autopll- This will not change becasue
-		byte clock does not need any divider*/
+		/* Set the source for DSI1 byte RCG */
 		writel(0x100, DSI_BYTE1_CFG_RCGR);
+		/* Set the update RCG bit */
 		writel(0x1, DSI_BYTE1_CMD_RCGR);
+		rcg_update_config(DSI_BYTE1_CMD_RCGR);
+		/* Enable the branch clock */
 		writel(0x1, DSI_BYTE1_CBCR);
+		branch_clk_halt_check(DSI_BYTE1_CBCR);
 
-		/* Configure Pixel clock */
+		/* Set the source for DSI1 pixel RCG */
 		writel(0x100, DSI_PIXEL1_CFG_RCGR);
-		writel(0x1, DSI_PIXEL1_CMD_RCGR);
-		writel(0x1, DSI_PIXEL1_CBCR);
-
+		/* Set the MND for DSI1 pixel clock */
 		writel(pclk0_m, DSI_PIXEL1_M);
 		writel(pclk0_n, DSI_PIXEL1_N);
 		writel(pclk0_d, DSI_PIXEL1_D);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_PIXEL1_CMD_RCGR);
+		rcg_update_config(DSI_PIXEL1_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_PIXEL1_CBCR);
+		branch_clk_halt_check(DSI_PIXEL1_CBCR);
 
 		/* Configure ESC clock */
 		ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
diff --git a/platform/msm8916/platform.c b/platform/msm8916/platform.c
index 6729667..8d0f033 100644
--- a/platform/msm8916/platform.c
+++ b/platform/msm8916/platform.c
@@ -202,6 +202,11 @@
 	return ret;
 }
 
+int platform_is_apq8016()
+{
+	return board_platform_id() == APQ8016 ? 1 : 0;
+}
+
 /* DYNAMIC SMEM REGION feature enables LK to dynamically
  * read the SMEM addr info from TCSR_TZ_WONCE register.
  * The first word read, if indicates a MAGIC number, then
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
index bdd1d6d..87e31dd 100644
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -36,6 +36,8 @@
 #include <platform/clock.h>
 #include <platform.h>
 
+#define MAX_LOOPS	500
+
 void hsusb_clock_init(void)
 {
 	int ret;
@@ -265,6 +267,34 @@
 	}
 }
 
+static void rcg_update_config(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(0)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(31)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
 /* Disable all the branch clocks needed by the DSI controller */
 void gcc_dsi_clocks_disable(void)
 {
@@ -278,20 +308,32 @@
 {
 	int ret;
 
-	/* Configure Byte clock -autopll- This will not change becasue
-	byte clock does not need any divider*/
+	/*
+	 * Configure Byte clock -autopll- This will not change becasue
+	 * byte clock does not need any divider
+	 */
+	/* Set the source for DSI0 byte RCG */
 	writel(0x100, DSI_BYTE0_CFG_RCGR);
+	/* Set the update RCG bit */
 	writel(0x1, DSI_BYTE0_CMD_RCGR);
+	rcg_update_config(DSI_BYTE0_CMD_RCGR);
+	/* Enable the branch clock */
 	writel(0x1, DSI_BYTE0_CBCR);
+	branch_clk_halt_check(DSI_BYTE0_CBCR);
 
 	/* Configure Pixel clock */
+	/* Set the source for DSI0 pixel RCG */
 	writel(0x100, DSI_PIXEL0_CFG_RCGR);
-	writel(0x1, DSI_PIXEL0_CMD_RCGR);
-	writel(0x1, DSI_PIXEL0_CBCR);
-
+	/* Set the MND for DSI0 pixel clock */
 	writel(pclk0_m, DSI_PIXEL0_M);
 	writel(pclk0_n, DSI_PIXEL0_N);
 	writel(pclk0_d, DSI_PIXEL0_D);
+	/* Set the update RCG bit */
+	writel(0x1, DSI_PIXEL0_CMD_RCGR);
+	rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+	/* Enable the branch clock */
+	writel(0x1, DSI_PIXEL0_CBCR);
+	branch_clk_halt_check(DSI_PIXEL0_CBCR);
 
 	/* Configure ESC clock */
 	ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
diff --git a/platform/msm8994/acpuclock.c b/platform/msm8994/acpuclock.c
index 6f4e0f0..533cf47 100644
--- a/platform/msm8994/acpuclock.c
+++ b/platform/msm8994/acpuclock.c
@@ -43,6 +43,8 @@
 #define CE2_CLK_ID         0x1
 #define RPM_SMD_KEY_RATE   0x007A484B
 
+#define MAX_LOOPS	500
+
 uint32_t CE2_CLK[][8]=
 {
 	{
@@ -455,6 +457,34 @@
 	clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
 }
 
+static void rcg_update_config(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(0)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(31)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
 void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t flags,
 			uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
 {
@@ -462,17 +492,28 @@
 
 	if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
 		/* Enable DSI0 branch clocks */
+
+		/* Set the source for DSI0 byte RCG */
 		writel(cfg_rcgr, DSI_BYTE0_CFG_RCGR);
+		/* Set the update RCG bit */
 		writel(0x1, DSI_BYTE0_CMD_RCGR);
+		rcg_update_config(DSI_BYTE0_CMD_RCGR);
+		/* Enable the branch clock */
 		writel(0x1, DSI_BYTE0_CBCR);
+		branch_clk_halt_check(DSI_BYTE0_CBCR);
 
+		/* Set the source for DSI0 pixel RCG */
 		writel(cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
-		writel(0x1, DSI_PIXEL0_CMD_RCGR);
-		writel(0x1, DSI_PIXEL0_CBCR);
-
+		/* Set the MND for DSI0 pixel clock */
 		writel(pclk0_m, DSI_PIXEL0_M);
 		writel(pclk0_n, DSI_PIXEL0_N);
 		writel(pclk0_d, DSI_PIXEL0_D);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_PIXEL0_CMD_RCGR);
+		rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_PIXEL0_CBCR);
+		branch_clk_halt_check(DSI_PIXEL0_CBCR);
 
 		ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
 		if(ret)
@@ -484,17 +525,28 @@
 
 	if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
 		/* Enable DSI1 branch clocks */
+
+		/* Set the source for DSI1 byte RCG */
 		writel(cfg_rcgr, DSI_BYTE1_CFG_RCGR);
+		/* Set the update RCG bit */
 		writel(0x1, DSI_BYTE1_CMD_RCGR);
+		rcg_update_config(DSI_BYTE1_CMD_RCGR);
+		/* Enable the branch clock */
 		writel(0x1, DSI_BYTE1_CBCR);
+		branch_clk_halt_check(DSI_BYTE1_CBCR);
 
+		/* Set the source for DSI1 pixel RCG */
 		writel(cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
-		writel(0x1, DSI_PIXEL1_CMD_RCGR);
-		writel(0x1, DSI_PIXEL1_CBCR);
-
+		/* Set the MND for DSI1 pixel clock */
 		writel(pclk0_m, DSI_PIXEL1_M);
 		writel(pclk0_n, DSI_PIXEL1_N);
 		writel(pclk0_d, DSI_PIXEL1_D);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_PIXEL1_CMD_RCGR);
+		rcg_update_config(DSI_PIXEL1_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_PIXEL1_CBCR);
+		branch_clk_halt_check(DSI_PIXEL1_CBCR);
 
 		ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
 		if(ret)
diff --git a/platform/msm8996/include/platform/gpio.h b/platform/msm8996/include/platform/gpio.h
index 5626d50..4d9c650 100644
--- a/platform/msm8996/include/platform/gpio.h
+++ b/platform/msm8996/include/platform/gpio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -57,4 +57,7 @@
 
 void gpio_config_uart_dm(uint8_t id);
 void gpio_config_blsp_i2c(uint8_t, uint8_t);
+void gpio_set(uint32_t gpio, uint32_t dir);
+void gpio_tlmm_config(uint32_t gpio, uint8_t func, uint8_t dir, uint8_t pull,
+		uint8_t drvstr, uint32_t enable);
 #endif
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 16fa8af..e112788 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -198,4 +198,333 @@
 
 #define MSM_MMSS_CLK_CTL_BASE       0x8C0000
 #define MMSS_MISC_AHB_CBCR          (MSM_MMSS_CLK_CTL_BASE + 0x5018)
+
+#define MIPI_DSI_BASE               (0x994000)
+#define MIPI_DSI0_BASE              (MIPI_DSI_BASE)
+#define MIPI_DSI1_BASE              (0x996000)
+#define DSI0_PHY_BASE               (0x994400)
+#define DSI1_PHY_BASE               (0x996400)
+#define DSI0_PLL_BASE               (0x994800)
+#define DSI1_PLL_BASE               (0x996800)
+#define DSI0_REGULATOR_BASE         (0x994000)
+#define DSI1_REGULATOR_BASE         (0x996000)
+
+#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE  0x0160
+#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0168
+
+#define MDP_BASE                    (0x900000)
+
+
+#ifdef MDP_PP_0_BASE
+#undef MDP_PP_0_BASE
+#endif
+#define MDP_PP_0_BASE               REG_MDP(0x71000)
+
+#ifdef MDP_PP_1_BASE
+#undef MDP_PP_1_BASE
+#endif
+#define MDP_PP_1_BASE               REG_MDP(0x71800)
+
+#define REG_MDP(off)                (MDP_BASE + (off))
+
+#ifdef MDP_HW_REV
+#undef MDP_HW_REV
+#endif
+#define MDP_HW_REV                              REG_MDP(0x1000)
+
+#ifdef MDP_INTR_EN
+#undef MDP_INTR_EN
+#endif
+#define MDP_INTR_EN                             REG_MDP(0x1010)
+
+#ifdef MDP_INTR_CLEAR
+#undef MDP_INTR_CLEAR
+#endif
+#define MDP_INTR_CLEAR                          REG_MDP(0x1018)
+
+#ifdef MDP_HIST_INTR_EN
+#undef MDP_HIST_INTR_EN
+#endif
+#define MDP_HIST_INTR_EN                        REG_MDP(0x101C)
+
+#ifdef MDP_DISP_INTF_SEL
+#undef MDP_DISP_INTF_SEL
+#endif
+#define MDP_DISP_INTF_SEL                       REG_MDP(0x1004)
+
+#ifdef MDP_VIDEO_INTF_UNDERFLOW_CTL
+#undef MDP_VIDEO_INTF_UNDERFLOW_CTL
+#endif
+#define MDP_VIDEO_INTF_UNDERFLOW_CTL            REG_MDP(0x12E0)
+
+#ifdef MDP_UPPER_NEW_ROI_PRIOR_RO_START
+#undef MDP_UPPER_NEW_ROI_PRIOR_RO_START
+#endif
+#define MDP_UPPER_NEW_ROI_PRIOR_RO_START        REG_MDP(0x11EC)
+
+#ifdef MDP_LOWER_NEW_ROI_PRIOR_TO_START
+#undef MDP_LOWER_NEW_ROI_PRIOR_TO_START
+#endif
+#define MDP_LOWER_NEW_ROI_PRIOR_TO_START        REG_MDP(0x13F8)
+
+#ifdef MDP_INTF_0_TIMING_ENGINE_EN
+#undef MDP_INTF_0_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_0_TIMING_ENGINE_EN             REG_MDP(0x6b000)
+
+#ifdef MDP_INTF_1_TIMING_ENGINE_EN
+#undef MDP_INTF_1_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_1_TIMING_ENGINE_EN             REG_MDP(0x6b800)
+
+#ifdef MDP_INTF_2_TIMING_ENGINE_EN
+#undef MDP_INTF_2_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_2_TIMING_ENGINE_EN             REG_MDP(0x6C000)
+
+#ifdef MDP_CTL_0_BASE
+#undef MDP_CTL_0_BASE
+#endif
+#define MDP_CTL_0_BASE				REG_MDP(0x2000)
+
+#ifdef MDP_CTL_1_BASE
+#undef MDP_CTL_1_BASE
+#endif
+#define MDP_CTL_1_BASE				REG_MDP(0x2200)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_EN
+#undef MDP_REG_SPLIT_DISPLAY_EN
+#endif
+#define MDP_REG_SPLIT_DISPLAY_EN                REG_MDP(0x12F4)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL
+#undef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL
+#endif
+#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL    REG_MDP(0x12F8)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL
+#undef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL
+#endif
+#define MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL    REG_MDP(0x13F0)
+
+#ifdef MDP_INTF_0_BASE
+#undef MDP_INTF_0_BASE
+#endif
+#define MDP_INTF_0_BASE                         REG_MDP(0x6b000)
+
+#ifdef MDP_INTF_1_BASE
+#undef MDP_INTF_1_BASE
+#endif
+#define MDP_INTF_1_BASE                         REG_MDP(0x6b800)
+
+#ifdef MDP_INTF_2_BASE
+#undef MDP_INTF_2_BASE
+#endif
+#define MDP_INTF_2_BASE                         REG_MDP(0x6c000)
+
+#ifdef MDP_CLK_CTRL0
+#undef MDP_CLK_CTRL0
+#endif
+#define MDP_CLK_CTRL0                           REG_MDP(0x12AC)
+
+#ifdef MDP_CLK_CTRL1
+#undef MDP_CLK_CTRL1
+#endif
+#define MDP_CLK_CTRL1                           REG_MDP(0x12B4)
+
+#ifdef MDP_CLK_CTRL2
+#undef MDP_CLK_CTRL2
+#endif
+#define MDP_CLK_CTRL2                           REG_MDP(0x12BC)
+
+#ifdef MDP_CLK_CTRL3
+#undef MDP_CLK_CTRL3
+#endif
+#define MDP_CLK_CTRL3                           REG_MDP(0x13A8)
+
+#ifdef MDP_CLK_CTRL4
+#undef MDP_CLK_CTRL4
+#endif
+#define MDP_CLK_CTRL4                           REG_MDP(0x13B0)
+
+#ifdef MDP_CLK_CTRL5
+#undef MDP_CLK_CTRL5
+#endif
+#define MDP_CLK_CTRL5                           REG_MDP(0x13B8)
+
+#ifdef MDP_CLK_CTRL6
+#undef MDP_CLK_CTRL6
+#endif
+#define MDP_CLK_CTRL6                           REG_MDP(0x12C4)
+
+#ifdef MDP_CLK_CTRL7
+#undef MDP_CLK_CTRL7
+#endif
+#define MDP_CLK_CTRL7                           REG_MDP(0x13D0)
+
+#ifdef MMSS_MDP_SMP_ALLOC_W_BASE
+#undef MMSS_MDP_SMP_ALLOC_W_BASE
+#endif
+#define MMSS_MDP_SMP_ALLOC_W_BASE               REG_MDP(0x1080)
+
+#ifdef MMSS_MDP_SMP_ALLOC_R_BASE
+#undef MMSS_MDP_SMP_ALLOC_R_BASE
+#endif
+#define MMSS_MDP_SMP_ALLOC_R_BASE               REG_MDP(0x1130)
+
+#ifdef MDP_QOS_REMAPPER_CLASS_0
+#undef MDP_QOS_REMAPPER_CLASS_0
+#endif
+#define MDP_QOS_REMAPPER_CLASS_0                REG_MDP(0x11E0)
+
+#ifdef MDP_QOS_REMAPPER_CLASS_1
+#undef MDP_QOS_REMAPPER_CLASS_1
+#endif
+#define MDP_QOS_REMAPPER_CLASS_1                REG_MDP(0x11E4)
+
+#ifdef VBIF_VBIF_DDR_FORCE_CLK_ON
+#undef VBIF_VBIF_DDR_FORCE_CLK_ON
+#endif
+#define VBIF_VBIF_DDR_FORCE_CLK_ON              REG_MDP(0xb0004)
+
+#ifdef VBIF_VBIF_DDR_OUT_MAX_BURST
+#undef VBIF_VBIF_DDR_OUT_MAX_BURST
+#endif
+#define VBIF_VBIF_DDR_OUT_MAX_BURST             REG_MDP(0xb00D8)
+
+#ifdef VBIF_VBIF_DDR_ARB_CTRL
+#undef VBIF_VBIF_DDR_ARB_CTRL
+#endif
+#define VBIF_VBIF_DDR_ARB_CTRL                  REG_MDP(0xb00F0)
+
+#ifdef VBIF_VBIF_DDR_RND_RBN_QOS_ARB
+#undef VBIF_VBIF_DDR_RND_RBN_QOS_ARB
+#endif
+#define VBIF_VBIF_DDR_RND_RBN_QOS_ARB           REG_MDP(0xb0124)
+
+#ifdef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0
+#undef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0
+#endif
+#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0        REG_MDP(0xb0160)
+
+#ifdef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1
+#undef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1
+#endif
+#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1        REG_MDP(0xb0164)
+
+#ifdef VBIF_VBIF_DDR_OUT_AOOO_AXI_EN
+#undef VBIF_VBIF_DDR_OUT_AOOO_AXI_EN
+#endif
+#define VBIF_VBIF_DDR_OUT_AOOO_AXI_EN           REG_MDP(0xb0178)
+
+#ifdef VBIF_VBIF_DDR_OUT_AX_AOOO
+#undef VBIF_VBIF_DDR_OUT_AX_AOOO
+#endif
+#define VBIF_VBIF_DDR_OUT_AX_AOOO               REG_MDP(0xb017C)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF0
+#undef VBIF_VBIF_IN_RD_LIM_CONF0
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF0               REG_MDP(0xb00B0)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF1
+#undef VBIF_VBIF_IN_RD_LIM_CONF1
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF1               REG_MDP(0xb00B4)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF2
+#undef VBIF_VBIF_IN_RD_LIM_CONF2
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF2               REG_MDP(0xb00B8)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF3
+#undef VBIF_VBIF_IN_RD_LIM_CONF3
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF3               REG_MDP(0xb00BC)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF0
+#undef VBIF_VBIF_IN_WR_LIM_CONF0
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF0               REG_MDP(0xb00C0)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF1
+#undef VBIF_VBIF_IN_WR_LIM_CONF1
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF1               REG_MDP(0xb00C4)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF2
+#undef VBIF_VBIF_IN_WR_LIM_CONF2
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF2               REG_MDP(0xb00C8)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF3
+#undef VBIF_VBIF_IN_WR_LIM_CONF3
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF3               REG_MDP(0xb00CC)
+
+#ifdef VBIF_VBIF_ABIT_SHORT
+#undef VBIF_VBIF_ABIT_SHORT
+#endif
+#define VBIF_VBIF_ABIT_SHORT                    REG_MDP(0xb0070)
+
+#ifdef VBIF_VBIF_ABIT_SHORT_CONF
+#undef VBIF_VBIF_ABIT_SHORT_CONF
+#endif
+#define VBIF_VBIF_ABIT_SHORT_CONF               REG_MDP(0xb0074)
+
+#ifdef VBIF_VBIF_GATE_OFF_WRREQ_EN
+#undef VBIF_VBIF_GATE_OFF_WRREQ_EN
+#endif
+#define VBIF_VBIF_GATE_OFF_WRREQ_EN             REG_MDP(0xb00A8)
+
+#define MDP_VP_0_VIG_0_BASE                     REG_MDP(0x5000)
+#define MDP_VP_0_VIG_1_BASE                     REG_MDP(0x7000)
+#define MDP_VP_0_RGB_0_BASE                     REG_MDP(0x15000)
+#define MDP_VP_0_RGB_1_BASE                     REG_MDP(0x17000)
+#define MDP_VP_0_DMA_0_BASE                     REG_MDP(0x25000)
+#define MDP_VP_0_DMA_1_BASE                     REG_MDP(0x27000)
+#define MDP_VP_0_MIXER_0_BASE                   REG_MDP(0x45000)
+#define MDP_VP_0_MIXER_1_BASE                   REG_MDP(0x46000)
+
+#define DMA_CMD_OFFSET              0x048
+#define DMA_CMD_LENGTH              0x04C
+
+#define INT_CTRL                    0x110
+#define CMD_MODE_DMA_SW_TRIGGER     0x090
+
+#define EOT_PACKET_CTRL             0x0CC
+#define MISR_CMD_CTRL               0x0A0
+#define MISR_VIDEO_CTRL             0x0A4
+#define VIDEO_MODE_CTRL             0x010
+#define HS_TIMER_CTRL               0x0BC
+
+#define SOFT_RESET                  0x118
+#define CLK_CTRL                    0x11C
+#define TRIG_CTRL                   0x084
+#define CTRL                        0x004
+#define COMMAND_MODE_DMA_CTRL       0x03C
+#define COMMAND_MODE_MDP_CTRL       0x040
+#define COMMAND_MODE_MDP_DCS_CMD_CTRL   0x044
+#define COMMAND_MODE_MDP_STREAM0_CTRL   0x058
+#define COMMAND_MODE_MDP_STREAM0_TOTAL  0x05C
+#define COMMAND_MODE_MDP_STREAM1_CTRL   0x060
+#define COMMAND_MODE_MDP_STREAM1_TOTAL  0x064
+#define ERR_INT_MASK0               0x10C
+
+#define LANE_CTL                    0x0AC
+#define LANE_SWAP_CTL               0x0B0
+#define TIMING_CTL                  0x0C4
+
+#define VIDEO_MODE_ACTIVE_H         0x024
+#define VIDEO_MODE_ACTIVE_V         0x028
+#define VIDEO_MODE_TOTAL            0x02C
+#define VIDEO_MODE_HSYNC            0x030
+#define VIDEO_MODE_VSYNC            0x034
+#define VIDEO_MODE_VSYNC_VPOS       0x038
+
+#define QPNP_LED_CTRL_BASE          0xD000
+#define QPNP_BLUE_LPG_CTRL_BASE     0xB100
+#define QPNP_GREEN_LPG_CTRL_BASE    0xB200
+#define QPNP_RED_LPG_CTRL_BASE      0xB300
+
 #endif
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 27296b4..5cd6576 100755
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -502,6 +502,11 @@
 
 	dprintf(CRITICAL, "DTB offset is incorrect, kernel image does not have appended DTB\n");
 
+	dprintf(INFO, "Device info 0x%08x/%08x/0x%08x/%u, pmic 0x%0x/0x%x/0x%x/0x%0x\n",
+			board_platform_id(), board_soc_version(),
+			board_target_id(), board_hardware_subtype(),
+			board_pmic_target(0), board_pmic_target(1),
+			board_pmic_target(2), board_pmic_target(3));
 	return NULL;
 }
 
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
index 0897b58..3bf5621 100644
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -331,6 +331,12 @@
 
 	fbcon_setup(&(panel->fb));
 	display_image_on_screen();
+
+	if (panel->dsi2HDMI_config)
+		ret = panel->dsi2HDMI_config(&(panel->panel_info));
+	if (ret)
+		goto msm_display_init_out;
+
 	ret = msm_display_config();
 	if (ret)
 		goto msm_display_init_out;
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
index 24f777d..fe5fd92 100644
--- a/platform/msm_shared/glink/glink_api.c
+++ b/platform/msm_shared/glink/glink_api.c
@@ -43,7 +43,7 @@
 #define GLINK_INITIALIZED     1
 
 /*===========================================================================
-                              GLOBAL DATA DECLARATIONS
+                        GLOBAL DATA DECLARATIONS
 ===========================================================================*/
 int glink_core_status = GLINK_NOT_INITIALIZED;
 
@@ -74,174 +74,249 @@
 /*===========================================================================
                     LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
-
+/*===========================================================================
+  FUNCTION      glinki_add_ch_to_xport
+===========================================================================*/
+/**
+ * Add remote/local channel context to xport open channel queue
+ *
+ * @param[in]    if_ptr            Pointer to xport if on which channel is to
+ *                                 be opened
+ * @param[in]    req_if_ptr        Pointer to xport if on which channel
+ *                                 actually wants to open
+ * @param[in]    ch_ctx            channel context
+ * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
+ * @param[in]    local_open        flag to determine if channel is opened
+ *                                 locally or remotely
+ * @param[in]    prio              negotiated xport priority
+ *                                 (used to send priority via remote_open_ack to
+ *                                  remote side)
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
 glink_err_type glinki_add_ch_to_xport
 (
   glink_transport_if_type  *if_ptr,
   glink_transport_if_type  *req_if_ptr,
   glink_channel_ctx_type   *ch_ctx,
-  glink_channel_ctx_type   **allocated_ch_ctx,
+  glink_channel_ctx_type  **allocated_ch_ctx,
   unsigned int              local_open,
-  boolean                      migration_state,
   glink_xport_priority      migrated_ch_prio
 )
 {
-  glink_err_type             status = 0;
+  glink_err_type             status;
   glink_channel_ctx_type     *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
 
   /* See if channel already exists in open_list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
+
+  for( open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+       open_ch_ctx;
+       open_ch_ctx = smem_list_next(open_ch_ctx) )
   {
-    if (strcmp(open_ch_ctx->name, ch_ctx->name) == 0)
+    if( 0 != glink_os_string_compare( open_ch_ctx->name, ch_ctx->name ) )
     {
-      /* We've found a channel name is already in the list of open channel */
-      /* increase reference open count for channel */
-      *allocated_ch_ctx = open_ch_ctx;
-      open_ch_ctx->ref_count++;
+      continue;
+    }
+    /* grab lock to avoid race condition for channel state change */
+    glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
 
-      /* Case A: Channel was opened before on the same host */
-      if((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) && local_open) {
-
-        open_ch_ctx->req_if_ptr = req_if_ptr;
-
-        /* Copy local open ctx params */
-        open_ch_ctx->notify_rx = ch_ctx->notify_rx;
-        open_ch_ctx->notify_rxv = ch_ctx->notify_rxv;
-        open_ch_ctx->notify_tx_done = ch_ctx->notify_tx_done;
-        open_ch_ctx->notify_state = ch_ctx->notify_state;
-        open_ch_ctx->notify_rx_intent_req = ch_ctx->notify_rx_intent_req;
-        open_ch_ctx->notify_rx_intent = ch_ctx->notify_rx_intent;
-        open_ch_ctx->notify_rx_sigs = ch_ctx->notify_rx_sigs;
-        open_ch_ctx->priv = ch_ctx->priv;
-        open_ch_ctx->ch_open_options = ch_ctx->ch_open_options;
-
-        /* release lock before context switch otherwise it is causing
-         * deadlock */
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        /* Send open cmd to transport */
-        status = if_ptr->tx_cmd_ch_open(if_ptr,
-                      open_ch_ctx->lcid, open_ch_ctx->name,
-                      open_ch_ctx->req_if_ptr->glink_priority);
-      }
-      else if ((open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN) &&
-               (!local_open))
-      {
-        /* Case B: Channel was opened on this end and we got a remote open */
-        open_ch_ctx->rcid = ch_ctx->rcid;
-
-        status = xport_ctx->channel_init(open_ch_ctx);
-
-        /* release lock before context switch otherwise it is causing deadlock */
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        if (status == GLINK_STATUS_SUCCESS)
-        {
-          /* Send ACK to transport */
-          if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, open_ch_ctx->rcid, migrated_ch_prio);
-        }
-      } else if ((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE)
-                  && (local_open)) {
-        /* Allocate new channel context */
-        break; /* code would break out of loop and create new ch ctx */
-      } else {
-        /* Can't handle this state */
-        ASSERT(0);
-      }
-
-      break;
-    } /* end if match found */
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  if (open_ch_ctx != NULL)
-  {
-    glink_os_free(ch_ctx);
-
-    /* connect channel here if state is local open and remote open request
-     * comes up and channel migration is done; channel will be connected in
-     * remote_open_ack if channel state is remote open and local open
-     * request comes up */
-    if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN &&
-       migration_state == FALSE && status == GLINK_STATUS_SUCCESS)
+    if( local_open )
     {
-      /* Set the channel state to OPEN */
-      open_ch_ctx->state = GLINK_CH_STATE_OPEN;
-      /* Inform the client */
-      open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-                                GLINK_CONNECTED);
-    }
-  }
-  else
-  {
-    /* Channel not in the list - it was not previously opened */
-    ch_ctx->if_ptr = if_ptr;
-    *allocated_ch_ctx = ch_ctx;
+      /* LOCAL OPEN REQUEST */
+      ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED );
 
-    /* Set channel state */
-    if (local_open) {
-      /* This is a local open */
-      ch_ctx->state      = GLINK_CH_STATE_LOCAL_OPEN;
-      ch_ctx->req_if_ptr = req_if_ptr;
-    }
-    else {
-      ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN;
-    }
+      glink_os_cs_init( &ch_ctx->tx_cs );
+      glink_os_cs_init( &ch_ctx->ch_state_cs );
 
-    glink_os_cs_init(&ch_ctx->tx_cs);
+      ch_ctx->rcid        = open_ch_ctx->rcid;
+      ch_ctx->lcid        = open_ch_ctx->lcid;
+      ch_ctx->pintents    = open_ch_ctx->pintents;
+      ch_ctx->if_ptr      = open_ch_ctx->if_ptr;
+      ch_ctx->req_if_ptr  = req_if_ptr;
 
-    /* Append the channel to the transport interface's open_list */
-    ch_ctx->ref_count++;
-    ch_ctx->lcid = xport_ctx->free_lcid;
-    xport_ctx->free_lcid++;
-    smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+      ch_ctx->remote_state = open_ch_ctx->remote_state;
+      ch_ctx->local_state  = GLINK_LOCAL_CH_OPENING;
 
-    /* release lock before context switch otherwise it is causing deadlock */
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
+      /* release lock before context switch otherwise it is causing
+       * deadlock */
+      smem_list_delete( &xport_ctx->open_list, open_ch_ctx );
+      smem_list_append( &xport_ctx->open_list, ch_ctx );
 
-    /* Send the OPEN command to transport */
-    if (local_open)
-    {
-      status = if_ptr->tx_cmd_ch_open(if_ptr, ch_ctx->lcid,
-                                      ch_ctx->name,
-                                      ch_ctx->req_if_ptr->glink_priority);
+      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+      glink_os_free( open_ch_ctx );
+      *allocated_ch_ctx = ch_ctx;
+      /* Send open cmd to transport */
+      status = if_ptr->tx_cmd_ch_open( if_ptr,
+                                       ch_ctx->lcid,
+                                       ch_ctx->name,
+                                       ch_ctx->req_if_ptr->glink_priority );
     }
     else
     {
-      /* initialize channel resources */
-      status = xport_ctx->channel_init(ch_ctx);
+      /* REMOTE OPEN REQUEST */
 
-      /* ACK the transport for remote open */
-      if (status == GLINK_STATUS_SUCCESS)
-      {
-        if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, ch_ctx->rcid,
-                                          migrated_ch_prio);
+      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+      {/* During SSR previous channel ctx needs to be destroyed
+        * new remote/local open request will create new context */
+        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+        continue;
       }
-    }
 
-    if (status != GLINK_STATUS_SUCCESS)
-    {
-      /* Remove the channel from the transport interface's open_list */
-      xport_ctx->free_lcid--;
+      ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED );
 
-      glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-      smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
+      open_ch_ctx->rcid = ch_ctx->rcid;
+      *allocated_ch_ctx = open_ch_ctx;
+      status = xport_ctx->channel_init(open_ch_ctx);
+
+      if( status == GLINK_STATUS_SUCCESS )
+      {
+        open_ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+      }
+
+      /* release lock before context switch otherwise it is causing deadlock */
+      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
       glink_os_cs_release(&xport_ctx->channel_q_cs);
 
-      /* free the ch_ctx structure and return */
-      xport_ctx->channel_cleanup(ch_ctx);
+
+      if ( status == GLINK_STATUS_SUCCESS )
+      {
+        /* Send ACK to transport */
+        if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
+                                           open_ch_ctx->rcid,
+                                           migrated_ch_prio );
+
+        /* Inform the client */
+        if( open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENED )
+        {
+          open_ch_ctx->notify_state( open_ch_ctx,
+                                     open_ch_ctx->priv,
+                                     GLINK_CONNECTED );
+        }
+      }
+
       glink_os_free(ch_ctx);
+    } /* end If - else (local_open) */
+
+    return status;
+  } /* end for */
+
+  ASSERT( open_ch_ctx == NULL );
+
+  /* Channel not in the list - it was not previously opened */
+  ch_ctx->if_ptr = if_ptr;
+  *allocated_ch_ctx = ch_ctx;
+
+  /* Set channel state */
+  if (local_open)
+  {
+    /* This is a local open */
+    ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
+    ch_ctx->req_if_ptr  = req_if_ptr;
+  }
+  else
+  {
+    ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+  }
+
+  glink_os_cs_init(&ch_ctx->tx_cs);
+  glink_os_cs_init(&ch_ctx->ch_state_cs);
+
+  /* Append the channel to the transport interface's open_list */
+  ch_ctx->lcid = xport_ctx->free_lcid;
+  xport_ctx->free_lcid++;
+  smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+
+  /* release lock before context switch otherwise it is causing deadlock */
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+  /* Send the OPEN command to transport */
+  if ( local_open )
+  {
+    status = if_ptr->tx_cmd_ch_open( if_ptr, ch_ctx->lcid,
+                                     ch_ctx->name,
+                                     ch_ctx->req_if_ptr->glink_priority );
+  }
+  else
+  {
+    /* initialize channel resources */
+    status = xport_ctx->channel_init(ch_ctx);
+
+    /* ACK the transport for remote open */
+    if (status == GLINK_STATUS_SUCCESS)
+    {
+      if_ptr->tx_cmd_ch_remote_open_ack( if_ptr, ch_ctx->rcid,
+                                         migrated_ch_prio );
     }
   }
 
+  if (status != GLINK_STATUS_SUCCESS)
+  {
+    /* Remove the channel from the transport interface's open_list */
+    xport_ctx->free_lcid--;
+    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+    smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+    /* free the ch_ctx structure and return */
+    xport_ctx->channel_cleanup(ch_ctx);
+    glink_os_free(ch_ctx);
+  }
+
   return status;
 }
 
-/** Default implementation of optional callbacks */
+/*===========================================================================
+  FUNCTION      glink_is_channel_fully_opened
+===========================================================================*/
+/**
+ * Check whether this channel is fully opened or not (local & remote)
+ * This also checks transport status
+ *
+ * @param[in]  handle        glink channel handle
+ * @param[in]  xport_ctx     glink transport core private
+ *
+ * @return     TRUE,  if channel is fully opened
+ *             FASLE, otherwise
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static boolean glink_is_channel_fully_opened
+(
+  glink_handle_type          handle,
+  glink_core_xport_ctx_type *xport_ctx
+)
+{
+  boolean ch_fully_opened = TRUE;
 
+  glink_os_cs_acquire( &handle->ch_state_cs );
+
+  if( handle->local_state != GLINK_LOCAL_CH_OPENED ||
+      handle->remote_state != GLINK_REMOTE_CH_OPENED )
+  {
+    ch_fully_opened = FALSE;
+  }
+
+  glink_os_cs_acquire( &xport_ctx->status_cs );
+  if( xport_ctx->status != GLINK_XPORT_LINK_UP )
+  {
+    ch_fully_opened = FALSE;
+  }
+
+  glink_os_cs_release( &xport_ctx->status_cs );
+  glink_os_cs_release( &handle->ch_state_cs );
+
+  return ch_fully_opened;
+}
+
+/** Default implementation of optional callbacks */
 static void glink_default_notify_rx_sigs
 (
   glink_handle_type  handle,
@@ -271,7 +346,7 @@
   link_notif_data->link_notifier(&link_info, link_notif_data->priv);
 }
 
-static uint32 glinki_find_remote_host
+uint32 glinki_find_remote_host
 (
   const char *remote_ss
 )
@@ -279,10 +354,11 @@
   uint32 remote_host;
   ASSERT(remote_ss);
 
-  for(remote_host = 0;
-      remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
-      remote_host++) {
-    if( 0 == strcmp(glink_hosts_supported[remote_host], remote_ss) ) {
+  for(remote_host = 0; remote_host < GLINK_NUM_HOSTS; remote_host++)
+  {
+    if( 0 == glink_os_string_compare( glink_hosts_supported[remote_host],
+                                      remote_ss ) )
+    {
       /* Match found, break out of loop */
       break;
     }
@@ -297,24 +373,18 @@
   glink_link_state_type      state
 )
 {
-  glink_link_info_type link_info;
-
   ASSERT(xport_ctx);
   ASSERT(link_notif_data);
 
-  link_info.xport = xport_ctx->xport;
-  link_info.remote_ss = xport_ctx->remote_ss;
-  link_info.link_state = state;
-
-  if(link_notif_data->xport == NULL ||
-     0 == strcmp(xport_ctx->xport, link_notif_data->xport)) {
+  if( link_notif_data->xport == NULL ||
+      0 == glink_os_string_compare( xport_ctx->xport, link_notif_data->xport ) )
+  {
     /* xport not specified, or it is specified and matches the current xport */
     /* Invoke registered callback */
-    link_notif_data->link_notifier(&link_info, link_notif_data->priv);
+    glinki_call_link_notifier(link_notif_data, xport_ctx, state);
   }
 }
 
-
 static void glinki_scan_xports_and_notify
 (
   glink_link_notif_data_type *link_notif_data
@@ -327,82 +397,33 @@
   ASSERT(link_notif_data);
 
   /* Find matching subsystem */
-  if(link_notif_data->remote_ss) {
-    remote_host = glinki_find_remote_host(link_notif_data->remote_ss);
+  for(remote_host = 0;
+      remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
+      remote_host++)
+  {
+    if ( link_notif_data->remote_ss != NULL &&
+         0 != glink_os_string_compare( glink_hosts_supported[remote_host],
+                                       link_notif_data->remote_ss ) )
+    {
+      /* client is not interested in this remote SS */
+      continue;
+    }
 
     /* Find the xport and give link UP notification */
-    if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-    if(if_ptr == NULL) {
-      /* No registered xports at this time, return without doing anything */
-      return;
-    }
+    for (if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+         if_ptr != NULL;
+         if_ptr = smem_list_next(if_ptr))
+    {
+      xport_ctx = if_ptr->glink_core_priv;
 
-    if(link_notif_data->xport) {
-      do {
-        xport_ctx = if_ptr->glink_core_priv;
-        if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
-          /* Match found, break out of loop */
-          break;
-        }
-      }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-
-      if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
+      if (xport_ctx->status == GLINK_XPORT_LINK_UP)
+      {
         /* Invoke registered callback */
-        glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                  GLINK_LINK_STATE_UP);
+        glinki_check_xport_and_notify( link_notif_data, xport_ctx,
+                                       GLINK_LINK_STATE_UP );
       }
-    } else {
-      /* No xport has been specified, invoke notifier for all registered
-       * xports */
-      do {
-        xport_ctx = if_ptr->glink_core_priv;
-        if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
-          /* Invoke registered callback */
-          glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                    GLINK_LINK_STATE_UP);
-        }
-      }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
     }
-  } else {
-    /* No remote ss is specified, invoke notifier for all remote_ss */
-    for(remote_host = 0;
-        remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
-        remote_host++) {
-      /* Find the xport and give link UP notification */
-      if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-      if(if_ptr == NULL) {
-        /* No registered xports at this time, continue with next remote_ss */
-        continue;
-      }
-
-      if(link_notif_data->xport) {
-        do {
-          xport_ctx = if_ptr->glink_core_priv;
-          if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
-            /* Match found, break out of loop */
-            break;
-          }
-        }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-
-        if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
-          /* Invoke registered callback */
-          glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                    GLINK_LINK_STATE_UP);
-        }
-      } else {
-        /* No xport has been specified, invoke notifier for all registered
-         * xports */
-        do {
-          xport_ctx = if_ptr->glink_core_priv;
-          if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
-            /* Invoke registered callback */
-            glinki_call_link_notifier(link_notif_data, xport_ctx,
-                                      GLINK_LINK_STATE_UP);
-          }
-        }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-      }
-    } /* end for remote_host */
-  }/* end if else (link_notif_data->remote_ss) */
+  } /* end for remote_host */
 } /* glinki_scan_xports_and_notify */
 
 void glinki_scan_notif_list_and_notify
@@ -414,26 +435,17 @@
   glink_link_notif_data_type *link_notif_data;
   glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
 
-  link_notif_data = smem_list_first(&glink_link_notif_list);
-
-  if(link_notif_data == NULL) {
-    /* list empty */
-    return;
+  for (link_notif_data = smem_list_first(&glink_link_notif_list);
+       link_notif_data != NULL;
+       link_notif_data = smem_list_next(link_notif_data))
+  {
+    if( link_notif_data->remote_ss == NULL ||
+        0 == glink_os_string_compare( xport_ctx->remote_ss,
+                                      link_notif_data->remote_ss ) )
+    {
+      glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
+    }
   }
-
-  do {
-      if(link_notif_data->remote_ss &&
-         0 == strcmp(xport_ctx->remote_ss, link_notif_data->remote_ss)) {
-        /* remote_ss specified and matches */
-        glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
-      } else if(link_notif_data->remote_ss == NULL) {
-        /* remote_ss not specified, invoke link notif for any remote_ss */
-        if(link_notif_data->xport) {
-          glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
-        } /* if else link_notif_data->xport */
-      } /* if else link_notif_data->remote_ss */
-  } while ( (link_notif_data = smem_list_next(link_notif_data)) != NULL);
-
 } /* glinki_scan_notif_list_and_notify */
 
 void glinki_scan_channels_and_notify_discon
@@ -441,7 +453,7 @@
   glink_transport_if_type *if_ptr
 )
 {
-  glink_channel_ctx_type *open_ch_ctx;
+  glink_channel_ctx_type     *open_ch_ctx, *dummy_open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
   ASSERT(if_ptr != NULL);
@@ -451,27 +463,46 @@
   /* Find channel in the open_list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
   open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
+  while( open_ch_ctx )
   {
-    /* Found channel, transition it to appropriate state based
-     * on current state */
-    if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
-      open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN;
+    glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+    open_ch_ctx->remote_state = GLINK_REMOTE_CH_SSR_RESET;
+    glink_os_cs_release( &open_ch_ctx->ch_state_cs );
 
-      /* Inform the client */
-      open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-          GLINK_REMOTE_DISCONNECTED);
-    } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
-      /* Local side never opened the channel */
-      /* Free channel resources */
-      xport_ctx->channel_cleanup(open_ch_ctx);
+    dummy_open_ch_ctx = smem_list_next( open_ch_ctx );
 
-      smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+    switch( open_ch_ctx->local_state )
+    {
+      case GLINK_LOCAL_CH_OPENED:
+      case GLINK_LOCAL_CH_OPENING:
+        /* local channel has called open at the moment. */
+        open_ch_ctx->notify_state( open_ch_ctx,
+                                   open_ch_ctx->priv,
+                                   GLINK_REMOTE_DISCONNECTED );
+        break;
 
-      glink_os_free(open_ch_ctx);
+      case GLINK_LOCAL_CH_CLOSING:
+        /* Case when local client already closed channel
+         * but has not received ack yet */
+        if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( if_ptr,
+                                                        open_ch_ctx->lcid );
+        break;
+
+      case GLINK_LOCAL_CH_CLOSED:
+        /* Channel fully closed - local, remote */
+        xport_ctx->channel_cleanup(open_ch_ctx);
+        smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+        glink_os_free(open_ch_ctx);
+        break;
+
+      default:
+        /* invalid local channel state */
+        ASSERT(0);
     }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
+
+    open_ch_ctx = dummy_open_ch_ctx;
+
+  } /* end while */
   glink_os_cs_release(&xport_ctx->channel_q_cs);
 }
 
@@ -487,15 +518,22 @@
      notification followed by REMOTE_DISCONNECT */
   if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
 
-  while(if_ptr != NULL) {
+  while(if_ptr != NULL)
+  {
+    /* xport is down. change the xport state */
+    glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
+    if_ptr->glink_core_priv->status = GLINK_XPORT_REGISTERED;
+
+    /* Let the xport know about ssr */
+    if_ptr->ssr( if_ptr );
+
     /* Invoke LINK_DOWN notification for any registered notifiers */
     glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
 
     /* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
     glinki_scan_channels_and_notify_discon(if_ptr);
 
-    /* Let the xport know about ssr */
-    if_ptr->ssr(if_ptr);
+    glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
     if_ptr = smem_list_next(if_ptr);
   }
@@ -597,32 +635,19 @@
     return GLINK_STATUS_INVALID_PARAM;;
   }
 
+  remote_host = glinki_find_remote_host(cfg->remote_ss);
 
-  /* Allocate/fill out the GLink Core interface structure */
-  {
-    glink_core_if_type *core_if = glink_os_calloc(sizeof(glink_core_if_type));
-    if(core_if == NULL) {
-      GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-          cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
-      return GLINK_STATUS_OUT_OF_RESOURCES;
-    }
-    core_if->link_up = glink_link_up;
-    core_if->rx_cmd_version = glink_rx_cmd_version;
-    core_if->rx_cmd_version_ack = glink_rx_cmd_version_ack;
-    core_if->rx_cmd_ch_remote_open = glink_rx_cmd_ch_remote_open;
-    core_if->rx_cmd_ch_open_ack = glink_rx_cmd_ch_open_ack;
-    core_if->rx_cmd_ch_close_ack = glink_rx_cmd_ch_close_ack;
-    core_if->rx_cmd_ch_remote_close = glink_rx_cmd_ch_remote_close;
-    core_if->ch_state_local_trans = glink_ch_state_local_trans;
-    core_if->rx_put_pkt_ctx = glink_rx_put_pkt_ctx;
-    core_if->rx_cmd_remote_sigs = glink_rx_cmd_remote_sigs;
-    core_if->tx_resume = glink_tx_resume;
-    core_if->set_core_version = glink_set_core_version;
+  if(remote_host == GLINK_NUM_HOSTS ) {
+    /* Unknown transport name trying to register with GLink */
+    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
+           cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
 
-    /* Set the glink_core_if_ptr to point to the allocated structure */
-    if_ptr->glink_core_if_ptr = core_if;
+    return GLINK_STATUS_INVALID_PARAM;
   }
 
+  /* Set the glink_core_if_ptr to point to the default interface */
+  if_ptr->glink_core_if_ptr = glink_core_get_default_interface();
+
   /* Allocate/fill out the GLink private context data */
   {
      xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
@@ -636,16 +661,15 @@
       return GLINK_STATUS_OUT_OF_RESOURCES;
     }
 
-    glink_os_string_copy(xport_ctx->xport, cfg->name,
-        sizeof(xport_ctx->xport));
-    glink_os_string_copy(xport_ctx->remote_ss, cfg->remote_ss,
-        sizeof(xport_ctx->xport));
+    xport_ctx->xport = cfg->name;
+    xport_ctx->remote_ss = cfg->remote_ss;
     xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
     xport_ctx->version_array = cfg->version;
     xport_ctx->version_indx = cfg->version_count - 1;
 
     glink_os_cs_init(&xport_ctx->channel_q_cs);
     glink_os_cs_init(&xport_ctx->liid_cs);
+    glink_os_cs_init(&xport_ctx->status_cs);
 
     glink_os_cs_acquire(&xport_ctx->channel_q_cs);
     smem_list_init(&xport_ctx->open_list);
@@ -657,15 +681,6 @@
   }
 
   /* Push the transport interface into appropriate queue */
-  remote_host = glinki_find_remote_host(cfg->remote_ss);
-
-  if(remote_host == GLINK_NUM_HOSTS ) {
-    /* Unknown transport name trying to register with GLink */
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, xport_ctx->xport,
-           xport_ctx->remote_ss, GLINK_STATUS_INVALID_PARAM);
-
-    return GLINK_STATUS_INVALID_PARAM;
-  }
   glink_os_cs_acquire(glink_transport_q_cs);
   smem_list_append(&glink_registered_transports[remote_host], if_ptr);
   glink_os_cs_release(glink_transport_q_cs);
@@ -732,6 +747,8 @@
   /* Append the request to the list for link UP/DOWN notifications */
   smem_list_append(&glink_link_notif_list, link_notif_data);
 
+  link_id->handle = (glink_link_handle_type)link_notif_data;
+
   /* Scan the list of available transport to see if this link is already up */
   glinki_scan_xports_and_notify(link_notif_data);
 
@@ -755,7 +772,12 @@
   glink_link_handle_type handle
 )
 {
-  ASSERT(handle);
+  /* check if glink handle is NULL and return appropriate
+     return code  */
+  if(handle == NULL)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
 
   smem_list_delete(&glink_link_notif_list,
                    (glink_link_notif_data_type*)handle);
@@ -789,18 +811,17 @@
 
   while(if_ptr != NULL)
   {
+    xport_ctx = if_ptr->glink_core_priv;
     /* check if priority of current transport is higher than
      * current highest priority (0 = highest priority)
      */
-    xport_ctx = if_ptr->glink_core_priv;
     if( xport_ctx->status == GLINK_XPORT_LINK_UP &&
         if_ptr->glink_priority < priority )
     {
       best_if_ptr = if_ptr;
       priority    = if_ptr->glink_priority;
     }
-
-    if_ptr    = smem_list_next(if_ptr);
+    if_ptr = smem_list_next(if_ptr);
   } /* end while() */
 
   return best_if_ptr;
@@ -924,14 +945,15 @@
                                        ch_ctx,
                                        &allocated_ch_ctx,
                                        TRUE,
-                                       TRUE,
                                        if_ptr->glink_priority );
 
-      if (status == GLINK_STATUS_SUCCESS) {
+      if( status == GLINK_STATUS_SUCCESS )
+      {
         /* Set the handle and return */
         *handle = allocated_ch_ctx;
       }
-      else {
+      else
+      {
         *handle = NULL;
       }
 
@@ -967,37 +989,61 @@
 )
 {
   glink_err_type status;
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
-  glink_ch_state_type ch_state;
+  glink_core_xport_ctx_type *xport_ctx = NULL;
 
-  if(handle == NULL) {
+  if(handle == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, NULL, "",
         "", GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  ch_state = handle->state;
+  /* get xport context after NULL check */
+  xport_ctx = handle->if_ptr->glink_core_priv;
 
-  /* Check to see if channel is in open/opening state */
-  if (ch_state != GLINK_CH_STATE_OPEN &&
-      ch_state != GLINK_CH_STATE_LOCAL_OPEN &&
-      ch_state != GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE &&
-      ch_state != GLINK_CH_STATE_REMOTE_OPEN)
+  /* grab lock to change/check channel state atomically */
+  glink_os_cs_acquire( &handle->ch_state_cs );
+
+  /* Check to see if closed called again for same channel */
+  if ( handle->local_state == GLINK_LOCAL_CH_CLOSING ||
+       handle->local_state == GLINK_LOCAL_CH_CLOSED )
   {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, ch_state);
+      xport_ctx->remote_ss, handle->local_state);
+
+    glink_os_cs_release(&handle->ch_state_cs);
+
     return GLINK_STATUS_FAILURE;
   }
 
-  /* Transition to closing */
-  //handle->state = GLINK_CH_STATE_CLOSING;
+  handle->local_state = GLINK_LOCAL_CH_CLOSING;
 
-  /* Send CLOSE cmd to the transport interface */
-  status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
-  GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, status);
+  glink_os_cs_acquire( &xport_ctx->status_cs );
+
+  if( GLINK_XPORT_LINK_UP != xport_ctx->status ||
+      handle->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+  {
+    /* SSR happened on remote-SS. Fake close_ack from here */
+    glink_os_cs_release( &xport_ctx->status_cs );
+    glink_os_cs_release( &handle->ch_state_cs );
+
+    handle->if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( handle->if_ptr,
+                                                            handle->lcid );
+
+    status = GLINK_STATUS_SUCCESS;
+  }
+  else
+  {
+    glink_os_cs_release( &xport_ctx->status_cs );
+    glink_os_cs_release( &handle->ch_state_cs );
+
+    status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
+
+    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+        xport_ctx->remote_ss, status);
+  }
+
   return status;
-
 }
 
 /**
@@ -1066,9 +1112,10 @@
 )
 {
   glink_err_type         status;
-  glink_core_tx_pkt_type pctx;
+  glink_core_tx_pkt_type *pctx;
   boolean                req_intent = options & GLINK_TX_REQ_INTENT;
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+
+  glink_core_xport_ctx_type *xport_ctx;
 
   /* Input validation */
   if(handle == NULL || iovec == NULL || size == 0 ||
@@ -1078,42 +1125,51 @@
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN )
+  xport_ctx = handle->if_ptr->glink_core_priv;
+
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  {
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_TX,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
+    return GLINK_STATUS_FAILURE;
+  }
+
+  pctx = glink_os_calloc( sizeof( glink_core_tx_pkt_type ) );
+
+  if (pctx == NULL)
   {
     GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
-    return GLINK_STATUS_FAILURE;
+      xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+    return GLINK_STATUS_OUT_OF_RESOURCES;
   }
 
   /* Protect the entire tx operation under a lock as a client may call
      tx in different thread context */
   glink_os_cs_acquire(&handle->tx_cs);
 
-  pctx.pkt_priv = pkt_priv;
-  pctx.size = size;
-  pctx.size_remaining = size;
-  pctx.vprovider = vprovider;
-  pctx.pprovider = pprovider;
+  pctx->pkt_priv = pkt_priv;
+  pctx->size = size;
+  pctx->size_remaining = size;
+  pctx->vprovider = vprovider;
+  pctx->pprovider = pprovider;
 
   if (vprovider == &glink_dummy_tx_vprovider)
   {
-    pctx.data = (void*)iovec;
-    pctx.iovec = &pctx;
+    pctx->data = (void*)iovec;
+    pctx->iovec = pctx;
   }
   else
   {
-    pctx.data = (void*)iovec;
-    pctx.iovec = iovec;
+    pctx->data = (void*)iovec;
+    pctx->iovec = iovec;
   }
 
-  status = xport_ctx->use_rm_intent(handle, &pctx, req_intent);
 
-  /* Call transport API to transmit data */
-  while (pctx.size_remaining != 0 && status == GLINK_STATUS_SUCCESS)
-  {
-    status = handle->if_ptr->tx(handle->if_ptr, handle->lcid, &pctx);
-  }
+  status = xport_ctx->channel_submit_pkt(handle, pctx, req_intent);
 
   GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, handle->name, xport_ctx->xport,
       xport_ctx->remote_ss, status);
@@ -1159,11 +1215,14 @@
     return GLINK_STATUS_FAILURE;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN)
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_Q_RX_INTENT,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
     return GLINK_STATUS_FAILURE;
   }
 
@@ -1271,11 +1330,14 @@
     return GLINK_STATUS_SUCCESS;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN)
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_RX_DONE,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
     return GLINK_STATUS_FAILURE;
   }
 
@@ -1353,7 +1415,7 @@
   uint32            sig_value
 )
 {
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+  glink_core_xport_ctx_type *xport_ctx;
   glink_err_type status;
 
   /* Input validation */
@@ -1363,11 +1425,16 @@
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  /* Make sure channel is in OPEN state */
-  if(handle->state != GLINK_CH_STATE_OPEN)
+  xport_ctx = handle->if_ptr->glink_core_priv;
+
+  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_SIG_SET,
+                     handle->name,
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss,
+                     GLINK_STATUS_FAILURE );
+
     return GLINK_STATUS_FAILURE;
   }
 
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
index 3c66369..5e3abd5 100644
--- a/platform/msm_shared/glink/glink_core_if.c
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -34,28 +34,26 @@
 #include "glink_os_utils.h"
 #include "glink.h"
 #include "glink_internal.h"
-#include "glink_core_if.h"
 #include "smem_list.h"
 #include "glink_channel_migration.h"
 
-
 #define FEATURE_CH_MIGRATION_FREE
 
-void glinki_scan_notif_list_and_notify
+/*===========================================================================
+                        GLOBAL FUNCTION DECLARATIONS
+==========================================================================*/
+extern void glinki_scan_notif_list_and_notify
 (
   glink_transport_if_type *if_ptr,
   glink_link_state_type state
 );
 
-/*===========================================================================
-                              GLOBAL DATA DECLARATIONS
-===========================================================================*/
 
 /*===========================================================================
                      LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
 /*===========================================================================
-FUNCTION      glink_process_negotiation_complete
+  FUNCTION      glink_process_negotiation_complete
 ===========================================================================*/
 /**
 
@@ -79,20 +77,26 @@
 /*=========================================================================*/
 static void glink_process_negotiation_complete
 (
-  glink_core_xport_ctx_type *xport_ctx,
   glink_transport_if_type   *if_ptr,
   uint32                    version,
   uint32                    features
 )
 {
+  glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
   /* Version/Feautre can be negotiated both in ver_req and ver_ack
    * Only go through process once in case they are negotiated
    * in ver_req before receiving ver_ack */
+
+  glink_os_cs_acquire( &xport_ctx->status_cs );
+
   if( xport_ctx->status == GLINK_XPORT_LINK_UP )
   {
+    glink_os_cs_release( &xport_ctx->status_cs );
     return;
   }
 
+  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
+
   /* setup core based on transport capabilities*/
   xport_ctx->xport_capabilities = if_ptr->set_version( if_ptr,
                                                        version,
@@ -100,38 +104,70 @@
   glink_core_setup(if_ptr);
 
   /* transport is ready to open channels */
+  glink_os_cs_acquire( &xport_ctx->status_cs );
   if_ptr->glink_core_priv->status = GLINK_XPORT_LINK_UP;
+  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
   /* Scan the notification list to check is we have to let any registered
-  * clients know that link came online */
+   * clients know that link came online */
   glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
 }
 
-static void glink_dummy_ch_migration_notification_cb
+
+/*===========================================================================
+  FUNCTION      glink_clean_channel_ctx
+===========================================================================*/
+/**
+
+  This is called when channel is fully closed
+  Clean up the context and redeem channel id if possible
+
+  @param[in]    xport_ctx    transport context
+  @param[in]    channel_ctx  channel context
+
+
+  @return        None
+  @sideeffects   None.
+  @dependencies  This function needs to be called in safe context
+                 which is critical sections locked - channel_q_cs
+*/
+/*=========================================================================*/
+static void glink_clean_channel_ctx
 (
-  glink_handle_type         handle,
-  const void               *priv,
-  glink_channel_event_type event
+  glink_core_xport_ctx_type *xport_ctx,
+  glink_channel_ctx_type    *channel_ctx
 )
 {
+  xport_ctx->channel_cleanup( channel_ctx );
+
+  if( channel_ctx->lcid == ( xport_ctx->free_lcid - 1 ) )
+  {
+    /* If channel being closed is the last opened channel
+       re-use the lcid of this channel for any new channels */
+    xport_ctx->free_lcid--;
+  }
+
+  smem_list_delete(&xport_ctx->open_list, channel_ctx);
 }
 
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 /*===========================================================================
-FUNCTION      glink_link_up
-
-DESCRIPTION   Indicates that transport is now ready to start negotiation
-              using the v0 configuration
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
+  FUNCTION      glink_link_up
 ===========================================================================*/
+/**
+  Indicates that transport is now ready to start negotiation
+  using the v0 configuration
+
+  @param[in]     if_ptr    Pointer to interface instance; must be unique
+                           for each edge
+
+  @return        None
+  @sideeffects   None.
+  @dependencies  None.
+*/
+/*=========================================================================*/
 void glink_link_up
 (
   glink_transport_if_type *if_ptr
@@ -147,7 +183,9 @@
   version_array = xport_ctx->version_array;
 
   /* Update the transport state */
+  glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
   if_ptr->glink_core_priv->status = GLINK_XPORT_NEGOTIATING;
+  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
   /* Start the negtiation */
   if_ptr->tx_cmd_version(if_ptr, version_array->version,
@@ -207,8 +245,7 @@
       /* send version ack before allowing to open channels */
       if_ptr->tx_cmd_version_ack(if_ptr, version, features);
 
-      glink_process_negotiation_complete( xport_ctx, if_ptr,
-                                          version, features );
+      glink_process_negotiation_complete( if_ptr, version, features );
       return;
     }
     else
@@ -277,8 +314,7 @@
     }
     else
     {
-      glink_process_negotiation_complete( xport_ctx, if_ptr,
-                                          version, features );
+      glink_process_negotiation_complete( if_ptr, version, features );
     }
   }
   else
@@ -323,64 +359,22 @@
   glink_xport_priority    priority
 )
 {
-  glink_channel_ctx_type *remote_ch_ctx;
-  glink_channel_ctx_type  *allocated_ch_ctx;
+  glink_channel_ctx_type     *remote_ch_ctx  = NULL;
+  glink_channel_ctx_type     *allocated_ch_ctx;
+
+  glink_xport_priority        negotiated_xport_priority;
   glink_core_xport_ctx_type  *xport_ctx;
-  glink_err_type status;
-  glink_xport_priority negotiated_prio;
-  boolean migration_state = TRUE;
+  glink_err_type              status;
 
-  ASSERT(if_ptr != NULL);
-  ASSERT(name != NULL);
-
-#ifndef FEATURE_CH_MIGRATION_FREE
-  glink_transport_if_type *present_if_ptr = NULL;
-  boolean channel_exist = FALSE;
-  glink_channel_ctx_type *present_ch_ctx = NULL;
-  /* search if channel with given name exists locally */
-  channel_exist = glinki_local_channel_exists(if_ptr, &present_if_ptr, name, &present_ch_ctx, TRUE);
-
-  /* start channel migration negotiation only if channel exists on local side
-   * for negotiation AND channel is willing to migrate */
-  if(channel_exist &&
-     (present_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
-  {
-    /* channel exists on one of the xports for given remote ss */
-    current_prio =  present_ch_ctx->req_if_ptr->glink_priority;
-    negotiated_prio = glinki_negotiate_ch_migration(priority, current_prio);
-
-    /* if current channel is open in same xport as negotiated xport
-     * local side wont migrate. Set migration flag to FALSE */
-    if(negotiated_prio == present_if_ptr->glink_priority)
-    {
-      migration_state = FALSE;
-    }
-  }
-  else if(channel_exist)
-  {
-    /* channel exists but channel does not want to be moved to another xport.
-       channel is set in stone */
-    negotiated_prio = present_if_ptr->glink_priority;
-    migration_state = FALSE;
-  }
-  else
-  {
-    /* channel does not exist on local side as yet
-     * return negotiated prio as current xport prio on which
-     * remote open request is received */
-    negotiated_prio = if_ptr->glink_priority;
-    migration_state = FALSE;
-  }
-#else
-  negotiated_prio = if_ptr->glink_priority;
-    migration_state = FALSE;
-#endif
+  ASSERT( if_ptr != NULL );
+  ASSERT( name != NULL );
 
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Allocate and initialize channel info structure */
-  remote_ch_ctx = glink_os_calloc(sizeof(glink_channel_ctx_type));
-  if(remote_ch_ctx == NULL) {
+  remote_ch_ctx = glink_os_calloc( sizeof( glink_channel_ctx_type ) );
+  if(remote_ch_ctx == NULL)
+  {
     GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
         xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
     ASSERT(0);
@@ -390,61 +384,113 @@
   glink_os_string_copy(remote_ch_ctx->name, name, sizeof(remote_ch_ctx->name));
   remote_ch_ctx->rcid = rcid;
 
-  status = glinki_add_ch_to_xport(if_ptr, NULL, remote_ch_ctx,
-                                  &allocated_ch_ctx, FALSE,
-                                  migration_state, negotiated_prio);
-  ASSERT(status == GLINK_STATUS_SUCCESS);
+#ifndef FEATURE_CH_MIGRATION_FREE
+  glink_channel_ctx_type     *present_ch_ctx = NULL;
+  glink_transport_if_type    *negotiated_xport;
+  glink_channel_ctx_type     *dummy_ch_ctx;
 
-  GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+  /* search if channel with given name exists locally */
+
+  glink_os_cs_acquire( &xport_ctx->channel_q_cs );
+  present_ch_ctx = glinki_local_channel_exists( if_ptr, name );
+
+  if( !present_ch_ctx )
+  {
+    // channel doesn't exists yet and migration will not happen here
+    status = glinki_add_ch_to_xport( if_ptr,
+                                     if_ptr,
+                                     remote_ch_ctx,
+                                     &allocated_ch_ctx,
+                                     FALSE,
+                                     if_ptr->glink_priority );
+    ASSERT(status == GLINK_STATUS_SUCCESS);
+
+    GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
       xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
 
-#ifndef FEATURE_CH_MIGRATION_FREE
-
-  /* We are done with channel migration negotiation at this stage
-   * Tag all channels with given name on xports other than negotiated
-   * xport for deletion */
-  glinki_tag_ch_for_deletion(if_ptr, name, negotiated_prio);
-
-    if(migration_state == TRUE)
-    {
-      glink_channel_ctx_type *new_ch_ctx;
-
-    /* create a new channel context as current channel will be migrated */
-    new_ch_ctx = (glink_channel_ctx_type *)
-                   glink_os_calloc(sizeof(glink_channel_ctx_type));
-
-    /* Fill in the channel info structure */
-    new_ch_ctx->req_if_ptr =
-             glinki_get_xport_from_prio(negotiated_prio,
-                                          if_ptr->glink_core_priv->remote_ss);
-    glink_os_string_copy(new_ch_ctx->name, present_ch_ctx->name,
-                         sizeof(present_ch_ctx->name));
-    new_ch_ctx->priv = present_ch_ctx->priv;
-    new_ch_ctx->notify_rx = present_ch_ctx->notify_rx;
-    new_ch_ctx->notify_rxv = present_ch_ctx->notify_rxv;
-    new_ch_ctx->notify_tx_done = present_ch_ctx->notify_tx_done;
-    new_ch_ctx->notify_state = present_ch_ctx->notify_state;
-    new_ch_ctx->notify_rx_intent_req = present_ch_ctx->notify_rx_intent_req;
-    new_ch_ctx->notify_rx_intent = present_ch_ctx->notify_rx_intent;
-    new_ch_ctx->notify_rx_sigs = present_ch_ctx->notify_rx_sigs;
-    new_ch_ctx->ch_open_options = present_ch_ctx->ch_open_options;
-
-//      glink_os_cs_init(&new_ch_ctx->intent_q_cs);
-
-    /* close current channel */
-    present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
-    if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
-
-    /* add new channel context on negotiated xport */
-    glinki_add_ch_to_xport(new_ch_ctx->req_if_ptr,
-                           new_ch_ctx->req_if_ptr,
-                           new_ch_ctx,
-                           &allocated_ch_ctx,
-                           TRUE,
-                           TRUE,
-                           new_ch_ctx->req_if_ptr->glink_priority);
+    glink_os_cs_release( &xport_ctx->channel_q_cs );
+    return;
   }
+
+  glink_os_cs_release( &xport_ctx->channel_q_cs );
+
+  present_ch_ctx->rcid = rcid;
+
+  if( present_ch_ctx->tag_ch_for_close )
+  {
+    // Migration already started.
+    GLINK_LOG_EVENT(GLINK_EVENT_CH_MIGRATION_IN_PROGRESS, name, xport_ctx->xport,
+      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+    return;
+  }
+
+  /* Negotiate the priority for migration if needed */
+  if( priority < present_ch_ctx->req_if_ptr->glink_priority )
+  {
+    negotiated_xport_priority = present_ch_ctx->req_if_ptr->glink_priority;
+  }
+  else
+  {
+    negotiated_xport_priority = priority;
+  }
+
+  negotiated_xport =  glinki_get_xport_from_prio( negotiated_xport_priority,
+                                                  xport_ctx->remote_ss );
+
+  if( if_ptr == negotiated_xport )
+  {
+    /* Current transport is best one. No need to migrate */
+
+    status = glinki_add_ch_to_xport( if_ptr,
+                                     if_ptr,
+                                     remote_ch_ctx,
+                                     &allocated_ch_ctx,
+                                     FALSE,
+                                     negotiated_xport_priority );
+
+    ASSERT(status == GLINK_STATUS_SUCCESS);
+    GLINK_LOG_EVENT( GLINK_EVENT_CH_NO_MIGRATION, name, xport_ctx->xport,
+      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+    return;
+  }
+
+  /* Need to migrate to new transport */
+  if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
+                                     rcid,
+                                     negotiated_xport_priority );
+
+  glink_create_dummy_ch_ctx( &dummy_ch_ctx, present_ch_ctx );
+  glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
+  glink_init_ch_migrate_candidate( present_ch_ctx );
+
+  status = glinki_add_ch_to_xport( negotiated_xport,
+                                   negotiated_xport,
+                                   present_ch_ctx,
+                                   &allocated_ch_ctx,
+                                   TRUE,
+                                   negotiated_xport_priority );
+
+  ASSERT( status == GLINK_STATUS_SUCCESS );
+
+  glink_os_free( remote_ch_ctx );
+
+#else
+  negotiated_xport_priority = if_ptr->glink_priority;
+
+  status = glinki_add_ch_to_xport( if_ptr,
+                                   NULL,
+                                   remote_ch_ctx,
+                                   &allocated_ch_ctx,
+                                   FALSE,
+                                   negotiated_xport_priority );
+
+  ASSERT(status == GLINK_STATUS_SUCCESS);
 #endif
+
+  GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+    xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
 }
 
 /*===========================================================================
@@ -467,11 +513,11 @@
 void glink_rx_cmd_ch_open_ack
 (
   glink_transport_if_type *if_ptr,
-  uint32                  lcid,
-  glink_xport_priority    migrated_ch_prio
+  uint32                   lcid,
+  glink_xport_priority     migrated_ch_prio
 )
 {
-  glink_channel_ctx_type *open_ch_ctx;
+  glink_channel_ctx_type     *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
   ASSERT(if_ptr != NULL);
@@ -480,121 +526,92 @@
 
   /* Move to closed state. Implies we clean up the channel from the
    * open list */
-
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
   /* Find channel in the open_list */
   open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
   while(open_ch_ctx != NULL)
   {
-    if(open_ch_ctx->lcid == lcid) {
+    if(open_ch_ctx->lcid == lcid)
+    {
 #ifndef FEATURE_CH_MIGRATION_FREE
-      glink_transport_if_type *present_if_ptr = NULL;
-      glink_channel_ctx_type  *present_ch_ctx = NULL;
-      boolean channel_exist;
-      /* find the channel in all xport list */
-      channel_exist = glinki_local_channel_exists(if_ptr,
-                                                  &present_if_ptr,
-                                                  open_ch_ctx->name,
-                                                  &present_ch_ctx,
-                                                  FALSE);
+      glink_transport_if_type    *negotiated_xport = NULL;
+      negotiated_xport = glinki_get_xport_from_prio( migrated_ch_prio,
+                                                     xport_ctx->remote_ss );
 
-      if(if_ptr->glink_priority == migrated_ch_prio && !channel_exist)
+      if( negotiated_xport != if_ptr &&
+          !open_ch_ctx->tag_ch_for_close &&
+          ( open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT ) )
       {
-        /* only local side has opened the channel. Remote side has not come up yet
-         * which implies negotiation did not take place on remote side */
-        /* DO NOTHING */
-      }
-      else if(if_ptr->glink_priority == migrated_ch_prio)
-      {
-        /* remote channel exists. channel migration negotiation happened
-         * on remote side and negotitated xport is same as current xport */
-        if(present_ch_ctx->ref_count == 1)
-        {
-          /* remote channel is present on different xport than negotiated one.
-           * remote side will migrate its channel to negotiated xport */
-          /* DO NOTHING */
-        }
-        else if(present_ch_ctx->ref_count == 2)
-        {
-          /* remote channel is open on same xport as current xport.
-           * change channel state to GLINK_CH_STATE_OPEN and notify client */
-          open_ch_ctx->state = GLINK_CH_STATE_OPEN;
-          open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-                                    GLINK_CONNECTED);
-        }
-        else
-        {
-          /* something went wrong in updating ref_count of channel */
-          ASSERT(0);
-        }
+        glink_channel_ctx_type *dummy_ch_ctx;
+        glink_err_type          status;
+
+        glink_create_dummy_ch_ctx( &dummy_ch_ctx, open_ch_ctx );
+        glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
+
+        glink_init_ch_migrate_candidate( open_ch_ctx );
+        dummy_ch_ctx = NULL;
+
+        status = glinki_add_ch_to_xport( negotiated_xport,
+                                         negotiated_xport,
+                                         open_ch_ctx,
+                                         &dummy_ch_ctx,
+                                         TRUE,
+                                         negotiated_xport->glink_priority );
+
+        ASSERT( status == GLINK_STATUS_SUCCESS );
       }
       else
       {
+        glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
 
-        /* migrated xport priority <> current xport priority */
-        /* check if remote channel is opened on negotiated xport already */
-          if(migrated_ch_prio == present_if_ptr->glink_priority &&
-             (open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
-          {
-            /* remote channel is already on negotiated xport. remote channel
-             * will not migrate. Local side should migrate */
-
-            glink_channel_ctx_type *new_ch_ctx =
-              (glink_channel_ctx_type *)glink_os_calloc(
-                                       sizeof(glink_channel_ctx_type));
-
-            /* Fill in the channel info structure */
-            glink_os_string_copy(new_ch_ctx->name,
-                                 open_ch_ctx->name,
-                                 sizeof(open_ch_ctx->name));
-            new_ch_ctx->priv = open_ch_ctx->priv;
-            new_ch_ctx->notify_rx = open_ch_ctx->notify_rx;
-            new_ch_ctx->notify_rxv = open_ch_ctx->notify_rxv;
-            new_ch_ctx->notify_tx_done = open_ch_ctx->notify_tx_done;
-            new_ch_ctx->notify_state = open_ch_ctx->notify_state;
-            new_ch_ctx->notify_rx_intent_req =
-                                            open_ch_ctx->notify_rx_intent_req;
-            new_ch_ctx->notify_rx_intent = open_ch_ctx->notify_rx_intent;
-            new_ch_ctx->notify_rx_sigs = open_ch_ctx->notify_rx_sigs;
-            new_ch_ctx->ch_open_options = open_ch_ctx->ch_open_options;
-
-            present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
-            if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
-
-            /* migrate to negotiated xport */
-            glinki_add_ch_to_xport(present_if_ptr,
-                                   present_if_ptr,
-                                   new_ch_ctx,
-                                   NULL,
-                                   TRUE,
-                                   TRUE,
-                                   present_if_ptr->glink_priority);
-          }
-          else
-          {
-            /* Either our transport is "set in stone"  OR */
-            /* remote side will migrate to negotiated xport and will call
-             * remote open on this side which will cause channel migration
-             * negotiation and this side will ultimately migrate */
-            /* DO NOTHING */
-          }
-        }
-#else
-        if(open_ch_ctx->ref_count == 2)
+        if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
         {
-          /* remote channel is open on same xport as current xport.
-           * change channel state to GLINK_CH_STATE_OPEN and notify client */
-          open_ch_ctx->state = GLINK_CH_STATE_OPEN;
-          open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
-                                    GLINK_CONNECTED);
+          /* Local client called glink_close
+           * before local channel is fully opened */
+          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+          glink_os_cs_release( &xport_ctx->channel_q_cs );
+          return;
         }
+
+        open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
+
+        if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
+        {
+          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+          open_ch_ctx->notify_state( open_ch_ctx,
+                                     open_ch_ctx->priv,
+                                     GLINK_CONNECTED );
+        }
+        else
+        {
+          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+        }
+      }
+
+#else
+      /* This is same code as above. once core capability code is done copy
+       * issue should be resolved */
+      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+      open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
+      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
+      {
+        /* remote channel is open on same xport as current xport.
+         * change channel state to GLINK_CH_STATE_OPEN and notify client */
+        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+        open_ch_ctx->notify_state( open_ch_ctx,
+                                   open_ch_ctx->priv,
+                                   GLINK_CONNECTED);
+      }
 #endif
 
       GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN_ACK, open_ch_ctx->name,
           xport_ctx->xport, xport_ctx->remote_ss, lcid);
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
       return;
     }
     open_ch_ctx = smem_list_next(open_ch_ctx);
   }
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
   /* We are here in case we could not find the channel in the open list. */
   ASSERT(0);
 }
@@ -632,55 +649,49 @@
 
   /* Find channel in the open_list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
+  open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+  while( open_ch_ctx )
   {
-    if(open_ch_ctx->lcid == lcid) {
+    if( open_ch_ctx->lcid == lcid )
+    {
       /* Found channel */
-      open_ch_ctx->ref_count--;
+      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+
+
       GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
           xport_ctx->xport, xport_ctx->remote_ss, lcid);
 
-      /* Transition state */
-      if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
-        /* this side initiated close procedure */
-        open_ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE;
-      } else if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN ||
-                open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE ||
-                open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
-        /* Other side never opened the port, or closed from its end */
-        /* Clear everything */
-        if(open_ch_ctx->ref_count == 0)
-        {
-          xport_ctx->channel_cleanup(open_ch_ctx);
-          /* re-use channel id if it can be done */
-          if(lcid == (xport_ctx->free_lcid-1)) {
-            /* If channel being closed is the last opened channel
-               re-use the lcid of this channel for any new channels */
-            xport_ctx->free_lcid--;
-          }
-          smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+      ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING );
 
-          /* Notify the client */
-          open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
-                                     GLINK_LOCAL_DISCONNECTED);
-          glink_os_free(open_ch_ctx);
-        }
-      } else {
-        /* Unsupported state */
-        ASSERT(0);
+      open_ch_ctx->local_state = GLINK_LOCAL_CH_CLOSED;
+
+      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
+          open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+      {
+        glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
       }
 
+      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
       glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+      open_ch_ctx->notify_state( open_ch_ctx,
+                                 open_ch_ctx->priv,
+                                 GLINK_LOCAL_DISCONNECTED );
+
+      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
+          open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+      {
+        glink_os_free( open_ch_ctx );
+      }
+
       return;
     }
     open_ch_ctx = smem_list_next(open_ch_ctx);
   }/* end while */
 
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
   /* We are here in case we could not find the channel in the open list. */
   ASSERT(0);
-
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
 }
 
 /*===========================================================================
@@ -712,124 +723,53 @@
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Find channel in the open_list */
-  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+  glink_os_cs_acquire( &xport_ctx->channel_q_cs );
+
+  open_ch_ctx = smem_list_first( &if_ptr->glink_core_priv->open_list );
   while(open_ch_ctx != NULL)
   {
-    if(open_ch_ctx->rcid == rcid) {
-        GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
-            xport_ctx->xport, xport_ctx->remote_ss, rcid);
-      /* Found channel, transition it to appropriate state based
-       * on current state */
-      open_ch_ctx->ref_count--;
+    if( open_ch_ctx->rcid == rcid )
+    {
+      GLINK_LOG_EVENT( GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
+                       xport_ctx->xport, xport_ctx->remote_ss, rcid);
+      /* Found channel, transition to appropriate state based on current state
+       * grab lock to perform channel state related operations */
+      glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
 
-      if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
-         open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE;
+      ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED );
 
+      open_ch_ctx->remote_state = GLINK_REMOTE_CH_CLOSED;
+
+      if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+      {
+        /* Local side never opened the channel OR it opened it but closed it */
+        /* Free channel resources */
+        glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
+      }
+
+      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+      /* Send the remote close ACK back to the other side */
+      if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+
+      if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+      {
+        glink_os_free(open_ch_ctx);
+      }
+      else
+      {
         /* Inform the client */
         open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
                                    GLINK_REMOTE_DISCONNECTED);
-
-        /* Send the remote close ACK back to the other side */
-        if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-
-        /* Free channel resources */
-        xport_ctx->channel_cleanup(open_ch_ctx);
-
-        GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
-            xport_ctx->xport, xport_ctx->remote_ss, rcid);
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        return;
-      } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN ||
-                 open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE) {
-        /* Local side never opened the channel OR it opened it but closed it */
-        /* Free channel resources */
-        xport_ctx->channel_cleanup(open_ch_ctx);
-
-        /* Send the remote close ACK back to the other side */
-        if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-
-        if(open_ch_ctx->ref_count == 0)
-        {
-          /* re-use channel id if it can be done */
-          if (open_ch_ctx->lcid == (xport_ctx->free_lcid - 1)) {
-            /* If channel being closed is the last opened channel
-            re-use the lcid of this channel for any new channels */
-            xport_ctx->free_lcid--;
-          }
-          smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
-          glink_os_free(open_ch_ctx);
-        }
-
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-        return;
-      } else {
-        /* SHould not get this callback for a channel in any other state */
-
-        //OS_LOG_ERROR(3, "GLINK_RX_CMD_CH_REMOTE_CLOSE: received close cmd for invalid state"
-        //                "[channel ctx: 0x%x][current channel state: %d]",
-        //                open_ch_ctx, open_ch_ctx->state );
-        glink_os_cs_release(&xport_ctx->channel_q_cs);
-        if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-        return;
       }
+
+      return;
     }
     open_ch_ctx = smem_list_next(open_ch_ctx);
   }/* end while */
 
-  /* We are here in case we could not find the channel in the open list
-   * or OPEN state. */
-  ASSERT(0);
-
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-}
-
-/*===========================================================================
-FUNCTION      glink_ch_state_local_trans
-
-DESCRIPTION   Process local state transition
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid      Remote Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_ch_state_local_trans
-(
-  glink_transport_if_type  *if_ptr,  /* Pointer to the interface instance */
-  uint32                   lcid,     /* Local channel ID */
-  glink_ch_state_type      new_state /* New local channel state */
-)
-{
-  glink_channel_ctx_type *open_ch_ctx;
-  glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
-
-  xport_ctx = if_ptr->glink_core_priv;
-
-  /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->lcid == lcid) {
-      /* Found channel, transition it to appropriate state */
-      open_ch_ctx->state = new_state;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_STATE_TRANS, open_ch_ctx->name,
-          xport_ctx->xport, xport_ctx->remote_ss, new_state);
-    return;
-  }/* end while */
-
-  /* We are here in case we could not find the channel in the open list
-   * or OPEN state. */
+  glink_os_cs_release( &xport_ctx->channel_q_cs );
   ASSERT(0);
 }
 
@@ -920,7 +860,16 @@
   open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
   while(open_ch_ctx != NULL)
   {
-    if(open_ch_ctx->rcid == rcid) {
+    if(open_ch_ctx->rcid == rcid ) {
+      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+      if( open_ch_ctx->local_state != GLINK_LOCAL_CH_OPENED &&
+          open_ch_ctx->remote_state != GLINK_REMOTE_CH_OPENED )
+      {
+        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+        ASSERT(0);
+        return;
+      }
+      glink_os_cs_release( &open_ch_ctx->ch_state_cs );
       /* Found channel, let client know of new remote signal state */
       prev_sigs = open_ch_ctx->remote_sigs;
       open_ch_ctx->remote_sigs = remote_sigs;
@@ -937,29 +886,6 @@
 
 
 /*===========================================================================
-FUNCTION      glink_tx_resume
-
-DESCRIPTION   If transport was full and could not continue a transmit
-              operation, then it will call this function to notify the core
-              that it is ready to resume transmission.
-
-ARGUMENTS   *if_ptr    Pointer to interface instance; must be unique
-                       for each edge
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_tx_resume
-(
-  glink_transport_if_type *if_ptr /* Pointer to the interface instance */
-)
-{
-  /* Not sure what to do here */
-}
-
-
-/*===========================================================================
 FUNCTION      glink_set_core_version
 
 DESCRIPTION   Sets the core version used by the transport; called after
diff --git a/platform/msm_shared/glink/glink_core_intentless_xport.c b/platform/msm_shared/glink/glink_core_intentless_xport.c
index 289ef18..98ced24 100644
--- a/platform/msm_shared/glink/glink_core_intentless_xport.c
+++ b/platform/msm_shared/glink/glink_core_intentless_xport.c
@@ -33,6 +33,55 @@
 #include "glink.h"
 #include "glink_internal.h"
 
+glink_core_if_type glink_core_intentless_interface =
+{
+  /** Indicates that transport is now ready to start negotiation using the
+   *  v0 configuration. */
+  glink_link_up,
+  /** Receive transport version for remote-initiated version negotiation */
+  glink_rx_cmd_version,
+  /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
+  glink_rx_cmd_version_ack,
+  /** Sets the core version used by the transport; called after completing
+   *  negotiation.*/
+  glink_set_core_version,
+  /** Receive remote channel open request; expected response is
+   *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
+  glink_rx_cmd_ch_remote_open,
+  /** This function is invoked by the transport in response to
+   *  glink_transport_if_type:: tx_cmd_ch_open */
+  glink_rx_cmd_ch_open_ack,
+  /** This function is invoked by the transport in response to
+   *  glink_transport_if_type:: tx_cmd_ch_close */
+  glink_rx_cmd_ch_close_ack,
+  /** Remote channel close request; will result in sending
+   *  glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
+  glink_rx_cmd_ch_remote_close,
+  /** Transport invokes this call on receiving remote RX intent */
+  NULL,
+  /** Get receive packet context (if successful, should be followed by call to
+      rx_put_pkt_ctx) */
+  NULL,
+  /** Receive a packet fragment (must have previously received an rx_cmd_rx_data
+      packet). */
+  glink_rx_put_pkt_ctx,
+  /** Transport invokes this call to inform GLink that remote side is
+   *   done with previous transmitted packet. */
+  NULL,
+  /** Remote side is requesting an RX intent */
+  NULL,
+  /** ACK to RX Intent Request */
+  NULL,
+  /** Received 32-bit signals value from remote side. It is passed on to
+   *  the client */
+  glink_rx_cmd_remote_sigs,
+  /** If transport was full and could not continue a transmit operation,
+   *  then it will call this function to notify the core that it is ready to
+   *  resume transmission. */
+  NULL
+};
+
+
 /*===========================================================================
 LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -104,10 +153,58 @@
 }
 
 /*===========================================================================
+FUNCTION      glink_channel_submit_pkt
+===========================================================================*/
+/**
+
+  Invokes intentless transport Tx function to transmit a packet
+
+  @param[in]  open_ch_ctx   Channel context.
+  @param[in]  pctx_ctx      Packet context.
+  @param[in]  req_intent    Request intent flag
+
+  @return     Error code.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+static glink_err_type glink_channel_submit_pkt_intentless
+(
+  glink_channel_ctx_type *open_ch_ctx,
+  glink_core_tx_pkt_type *pctx,
+  boolean req_intent
+)
+{
+  glink_transport_if_type *if_ptr = open_ch_ctx->if_ptr;
+  glink_err_type status = if_ptr->tx(if_ptr, open_ch_ctx->lcid, pctx);
+
+  glink_os_free(pctx);
+
+  return status;
+}
+
+/*===========================================================================
 EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 
 /*===========================================================================
+  FUNCTION      glink_core_get_intentless_interface
+===========================================================================*/
+/**
+
+  Provides core interface for the intentless transport.
+
+  @return     Pointer to the core intentless interface.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_intentless_interface(void)
+{
+  return &glink_core_intentless_interface;
+}
+
+/*===========================================================================
   FUNCTION      glink_core_setup_intentless_xport
 ===========================================================================*/
 /**
@@ -123,9 +220,10 @@
 /*=========================================================================*/
 void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr)
 {
+  if_ptr->glink_core_if_ptr = glink_core_get_intentless_interface();
   if_ptr->glink_core_priv->verify_open_cfg = glink_verify_open_cfg_intentless;
   if_ptr->glink_core_priv->channel_init = (channel_init_fn)glink_core_stub_intentless;
   if_ptr->glink_core_priv->channel_cleanup = (channel_cleanup_fn)glink_core_stub_intentless;
-  if_ptr->glink_core_priv->use_rm_intent = (use_rm_intent_fn)glink_core_stub_intentless;
+  if_ptr->glink_core_priv->channel_submit_pkt = glink_channel_submit_pkt_intentless;
   if_ptr->glink_core_priv->channel_receive_pkt = glink_channel_receive_pkt_intentless;
 }
diff --git a/platform/msm_shared/glink/glink_os_utils_dal.c b/platform/msm_shared/glink/glink_os_utils_dal.c
index 7ad6fb7..311890e 100644
--- a/platform/msm_shared/glink/glink_os_utils_dal.c
+++ b/platform/msm_shared/glink/glink_os_utils_dal.c
@@ -56,6 +56,7 @@
   void                    *param;
 }glink_os_thread_info_type;
 
+static uint32 cs_variable = 1;
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -102,6 +103,23 @@
 }
 
 /*===========================================================================
+FUNCTION      glink_os_cs_create
+===========================================================================*/
+/**
+  Create and initializesa Critical Section
+
+  @return     The critical section.
+*/
+/*=========================================================================*/
+os_cs_type *glink_os_cs_create( void )
+{
+  /* Create the new critical section */
+
+  return ( os_cs_type * )cs_variable;
+}
+
+
+/*===========================================================================
 FUNCTION      glink_os_cs_acquire
 ===========================================================================*/
 /**
@@ -248,15 +266,14 @@
 
   @param[in] s1     String 1
   @param[in] s2     String 2
-  @param[in] size   The maximum number of characters to compare
 
   @return
   0 if strings are identical (up to size characters), non-zero otherwise
 */
 /*==========================================================================*/
-long glink_os_string_compare( const char *s1, const char *s2, uint32 size )
+long glink_os_string_compare( const char *s1, const char *s2 )
 {
-  return strncmp( s1, s2, size );
+  return strcmp( s1, s2 );
 }
 
 /*===========================================================================
diff --git a/platform/msm_shared/glink/glink_rpmcore_setup.c b/platform/msm_shared/glink/glink_rpmcore_setup.c
index a206afa..573d68d 100644
--- a/platform/msm_shared/glink/glink_rpmcore_setup.c
+++ b/platform/msm_shared/glink/glink_rpmcore_setup.c
@@ -34,11 +34,30 @@
 #include "glink_internal.h"
 
 
+glink_core_if_type* glink_core_get_intentless_interface(void);
+
 /*===========================================================================
 EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
 
 /*===========================================================================
+FUNCTION      glink_core_get_default_interface
+===========================================================================*/
+/**
+
+  Provides default core interface.
+
+  @return     Pointer to the default core interface.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_default_interface(void)
+{
+  return glink_core_get_intentless_interface();
+}
+
+/*===========================================================================
 FUNCTION      glink_core_setup
 ===========================================================================*/
 /**
diff --git a/platform/msm_shared/glink/xport_rpm.c b/platform/msm_shared/glink/xport_rpm.c
index 05329f9..68a6c80 100644
--- a/platform/msm_shared/glink/xport_rpm.c
+++ b/platform/msm_shared/glink/xport_rpm.c
@@ -135,7 +135,7 @@
   }
 
   last = ctx_ptr->rx_fifo_size - ctx_ptr->pkt_start_ind;
-
+  
   if (offset >= last)
   {
     *size = ctx_ptr->pkt_size - offset;
@@ -235,7 +235,7 @@
     *write_ptr++ = *buffer++;
   }
 
-  return (char*)write_ptr - &ctx_ptr->tx_fifo[0];
+  return (uint32)((char*)write_ptr - &ctx_ptr->tx_fifo[0]);
 }
 
 /*===========================================================================
@@ -271,12 +271,19 @@
 
   glink_os_cs_acquire(ctx_ptr->tx_link_lock);
 
+  /* Transport is in reset */
+  if( ctx_ptr->reset )
+  {
+    glink_os_cs_release(ctx_ptr->tx_link_lock);
+    return GLINK_STATUS_SUCCESS;
+  }
+
   write_ind = ctx_ptr->tx_desc->write_ind;
   read_ind = ctx_ptr->tx_desc->read_ind;
   avail_size = write_ind < read_ind ? read_ind - write_ind :
                ctx_ptr->tx_fifo_size - write_ind + read_ind;
 
-  if (reserve_size + sizeof(uint64_t) > avail_size)
+  if (reserve_size + sizeof(uint64) > avail_size)
   {
     glink_os_cs_release(ctx_ptr->tx_link_lock);
     return GLINK_STATUS_OUT_OF_RESOURCES;
@@ -449,7 +456,7 @@
 
   cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_OPEN_CHANNEL);
   cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
-  cmd[1] =  strlen(name) + 1;
+  cmd[1] =  (uint32)strlen(name) + 1;
 
   return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)name, cmd[1]);
 }
@@ -584,12 +591,12 @@
   cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_TX_DATA);
   cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
   cmd[1] = 0;
-  cmd[2] = pctx->size;
+  cmd[2] = (uint32)pctx->size;
   cmd[3] = 0;
 
   pctx->size_remaining = 0;
 
-  return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, pctx->size);
+  return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, (uint32)pctx->size);
 }
 
 /*===========================================================================
@@ -652,11 +659,11 @@
 }
 
 /*===========================================================================
-FUNCTION      xport_rpm_poll
+FUNCTION      xport_rpm_isr
 ===========================================================================*/
 /**
 
-  Poll of RPM transport.
+  ISR of RPM transport.
 
   @param[in]  ctx_ptr   Pointer to transport context.
 
@@ -667,7 +674,7 @@
   @dependencies None.
 */
 /*=========================================================================*/
-glink_err_type xport_rpm_poll( xport_rpm_ctx_type *ctx_ptr )
+glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
 {
   uint32 write_ind, read_ind;
   boolean stop_processing = FALSE;
@@ -712,7 +719,7 @@
 
         cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
 
-        /* no need to incerment read_ind here since it will be rounded up */
+        /* no need to increment read_ind here since it will be rounded up */
 
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_version(
           (glink_transport_if_type *)ctx_ptr,
@@ -744,56 +751,53 @@
         }
         else
         {
-          char    tmpstr[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
-          uint32  curr = 0;
-          uint32* string_ptr;
-          string_ptr = (uint32 *)&tmpstr[0];
-          while (curr < cmd_arg && curr < sizeof(tmpstr))
+          char  temp_string[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
+          uint32 num_copied_chars = 0;
+          uint32  *string_ptr;
+
+          string_ptr = ( uint32 * )&temp_string[0];
+          while( ( num_copied_chars < cmd_arg ) && ( num_copied_chars < sizeof( temp_string ) ) )
           {
-            CHECK_INDEX_WRAP_AROUND(read_ind, ctx_ptr->rx_fifo_size);
-            *(string_ptr++) = MSGRAM_READ32(ctx_ptr, read_ind);
-            curr += sizeof(uint32);
-            read_ind += sizeof(uint32);
+            CHECK_INDEX_WRAP_AROUND( read_ind, ctx_ptr->rx_fifo_size );
+            *( string_ptr++ ) = MSGRAM_READ32( ctx_ptr, read_ind );
+
+            num_copied_chars += sizeof( uint32 );
+            read_ind += sizeof( uint32 );
           }
 
           /* add all the unread stuff */
-          read_ind += cmd_arg - curr;
+          read_ind += cmd_arg - num_copied_chars;
 
           /* make sure the last character is NULL */
-          tmpstr[sizeof(tmpstr) - 1] = 0;
+          temp_string[ sizeof( temp_string ) - 1 ] = 0;
 
           ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
-            (glink_transport_if_type *)ctx_ptr, cid, tmpstr, GLINK_XPORT_RPM);
+            (glink_transport_if_type *)ctx_ptr, cid, temp_string, GLINK_XPORT_RPM);
         }
 
         break;
 
       case XPORT_RPM_CMD_CLOSE_CHANNEL:
 
+        /* no need to increment read_ind here since it will be rounded up */
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_close(
-          //(glink_transport_if_type *)ctx_ptr, XPORT_RPM_GET_CHANNEL_ID(cmd));
           (glink_transport_if_type *)ctx_ptr, cid);
 
-        /* no need to increment read_ind here since it would be rounded up */
-
         break;
 
       case XPORT_RPM_CMD_OPEN_CHANNEL_ACK:
 
-        /* no need to increment read_ind here since it would be rounded up */
-
+        /* no need to increment read_ind here since it will be rounded up */
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_open_ack(
             (glink_transport_if_type *)ctx_ptr, cid, GLINK_XPORT_RPM);
 
         break;
 
       case XPORT_RPM_CMD_CLOSE_CHANNEL_ACK:
-
+        /* no need to increment read_ind here since it will be rounded up */
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_close_ack(
           (glink_transport_if_type *)ctx_ptr, cid);
 
-        /* no need to increment read_ind here since it would be rounded up */
-
         break;
 
       case XPORT_RPM_CMD_TX_DATA:
@@ -843,7 +847,7 @@
 
         cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
 
-        /* no need to incerement read_ind here since it will be rounded up */
+        /* no need to increment read_ind here since it will be rounded up */
 
         ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_remote_sigs(
           (glink_transport_if_type *)ctx_ptr,
@@ -851,20 +855,28 @@
         break;
 
       default:
-      	dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
-      	ASSERT(0);
+        dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
+        ASSERT(0);
         break;
     }
 
-    read_ind = ROUNDUP64(read_ind);
-
-    if (read_ind >= ctx_ptr->rx_fifo_size)
+    /* Update read index only if transport has not been reset  */
+    if( !ctx_ptr->reset )
     {
-      read_ind -= ctx_ptr->rx_fifo_size;
-    }
+      read_ind = ROUNDUP64(read_ind);
 
-    /* Update the shared read index */
-    ctx_ptr->rx_desc->read_ind = read_ind;
+      if (read_ind >= ctx_ptr->rx_fifo_size)
+      {
+        read_ind -= ctx_ptr->rx_fifo_size;
+      }
+
+      /* Update the shared read index */
+      ctx_ptr->rx_desc->read_ind = read_ind;
+    }
+    else
+    {
+      stop_processing = TRUE;
+    }
   }
 
   glink_os_cs_release(ctx_ptr->rx_link_lock);
@@ -872,51 +884,6 @@
   return GLINK_STATUS_SUCCESS;
 }
 
-#ifdef GLINK_RPM_PROC
-/*===========================================================================
-FUNCTION      xport_rpm_isr
-===========================================================================*/
-/**
-
-  ISR of RPM transport.
-
-  @return     Returns error code.
-
-  @sideeffects  None.
-
-  @dependencies None.
-*/
-/*=========================================================================*/
-glink_err_type xport_rpm_isr( void )
-{
-  xport_rpm_ctx_type *ctx_ptr  = xport_rpm_get_context();
-
-  return xport_rpm_poll( ctx_ptr );
-}
-#else
-/*===========================================================================
-FUNCTION      xport_rpm_isr
-===========================================================================*/
-/**
-
-  ISR of RPM transport.
-
-  @param[in]  ctx_ptr   Pointer to transport context.
-
-  @return     Returns error code.
-
-  @sideeffects  None.
-
-  @dependencies None.
-*/
-/*=========================================================================*/
-glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
-{
-  return xport_rpm_poll( ctx_ptr );
-}
-#endif
-
-
 /*===========================================================================
 FUNCTION      xport_rpm_ssr
 ===========================================================================*/
@@ -935,9 +902,15 @@
 {
   xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
 
+  glink_os_cs_acquire(ctx_ptr->tx_link_lock);
+  glink_os_cs_acquire(ctx_ptr->rx_link_lock);
   ctx_ptr->tx_desc->write_ind = 0;
+  ctx_ptr->tx_desc->read_ind = 0;
+  ctx_ptr->rx_desc->write_ind = 0;
   ctx_ptr->rx_desc->read_ind = 0;
   ctx_ptr->reset = TRUE;
+  glink_os_cs_release(ctx_ptr->rx_link_lock);
+  glink_os_cs_release(ctx_ptr->tx_link_lock);
 
   return GLINK_STATUS_SUCCESS;
 }
@@ -1004,6 +977,25 @@
 }
 
 /*===========================================================================
+FUNCTION      xport_rpm_is_toc_present
+===========================================================================*/
+/**
+
+  Checks RPM MSG RAM for ToC presence.
+
+  @return     TRUE if ToC is detected, FALSE otherwise.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+boolean xport_rpm_is_toc_present(void)
+{
+  uint32 *msg_ram_toc = (uint32*)xport_rpm_msg_ram_toc;
+
+  return msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] == XPORT_RPM_TOC_MAGIC;
+}
+
+/*===========================================================================
 FUNCTION      xport_rpm_init
 ===========================================================================*/
 /**
@@ -1033,8 +1025,9 @@
     return GLINK_STATUS_SUCCESS;
   }
 
-  if (msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] != XPORT_RPM_TOC_MAGIC)
+  if (!xport_rpm_is_toc_present())
   {
+    /* switch to err fatal once RPM side is integrated */
     dprintf(CRITICAL, "%s:%d: RPM Transport Failure: Invalid ToC cookie\n", __func__, __LINE__);
     return GLINK_STATUS_FAILURE;
   }
@@ -1076,14 +1069,12 @@
       if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->tx_fifo_id)
       {
         xport_rpm_ctx[ind].tx_desc = (xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
-        xport_rpm_ctx[ind].tx_desc->write_ind = 0;
         xport_rpm_ctx[ind].tx_fifo = (char*)(xport_rpm_ctx[ind].tx_desc + 1);
         xport_rpm_ctx[ind].tx_fifo_size = entry->fifo_size;
       }
       else if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->rx_fifo_id)
       {
         xport_rpm_ctx[ind].rx_desc =(xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
-        xport_rpm_ctx[ind].rx_desc->read_ind = 0;
         xport_rpm_ctx[ind].rx_fifo = (char*)(xport_rpm_ctx[ind].rx_desc + 1);
         xport_rpm_ctx[ind].rx_fifo_size = entry->fifo_size;
       }
@@ -1096,9 +1087,13 @@
       continue;
     }
 
+    /* Rx read index should be cleared last */
+    xport_rpm_ctx[ind].tx_desc->write_ind = 0;
+    xport_rpm_ctx[ind].rx_desc->read_ind = 0;
+
     /* Initialize context */
-    xport_rpm_ctx[ind].tx_link_lock = NULL;
-    xport_rpm_ctx[ind].rx_link_lock = NULL;
+    xport_rpm_ctx[ind].tx_link_lock = glink_os_cs_create();
+    xport_rpm_ctx[ind].rx_link_lock = glink_os_cs_create();
 
     /* Initialize GLink transport interface */
     xport_rpm_ctx[ind].xport_if.tx_cmd_version = &xport_rpm_tx_cmd_version;
@@ -1112,7 +1107,7 @@
     xport_rpm_ctx[ind].xport_if.tx_cmd_set_sigs = &xport_rpm_tx_cmd_set_sigs;
     xport_rpm_ctx[ind].xport_if.ssr = &xport_rpm_ssr;
     xport_rpm_ctx[ind].xport_if.mask_rx_irq = &xport_rpm_mask_interrupt;
-    xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_poll;
+    xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_isr;
     xport_rpm_ctx[ind].xport_if.wait_link_down = &xport_rpm_wait_link_down;
 
     /* TODO: glink transport priority */
@@ -1125,6 +1120,7 @@
     xport_rpm_cfg.version_count = 1;
     xport_rpm_cfg.max_cid = 0xFF;
     xport_rpm_cfg.max_iid = 0;
+
     if (glink_core_register_transport(&xport_rpm_ctx[ind].xport_if, &xport_rpm_cfg) !=
         GLINK_STATUS_SUCCESS)
     {
@@ -1137,7 +1133,8 @@
                                 (os_isr_cb_fn)xport_rpm_isr,
                                 &xport_rpm_ctx[ind]) )
     {
-       /* ISR registration failed, set index to invalid. */
+       /* ISR registration failed, set index to invalid.
+        * It will never fail */
       xport_rpm_ctx[ind].pcfg = NULL;
       continue;
     }
diff --git a/platform/msm_shared/include/glink.h b/platform/msm_shared/include/glink.h
index fe5b823..b36fba0 100644
--- a/platform/msm_shared/include/glink.h
+++ b/platform/msm_shared/include/glink.h
@@ -102,6 +102,9 @@
                           (link_id).version = GLINK_LINK_ID_VER;
 
 /* GLink tx options */
+/* Flag for no options */
+#define GLINK_TX_NO_OPTIONS      ( 0 )
+
 /* Whether to block and request for remote rx intent in
  * case it is not available for this pkt tx */
 #define GLINK_TX_REQ_INTENT      0x00000001
@@ -111,6 +114,9 @@
  * it is not able to do so */
 #define GLINK_TX_SINGLE_THREADED 0x00000002
 
+/* This option is to turn on tracer packet */
+#define GLINK_TX_TRACER_PKT      0x00000004
+
 /* ======================= glink open cfg options ==================*/
 
 /* Specified transport is just the initial transport and migration is possible
@@ -205,6 +211,17 @@
   size_t            intent_used /* size of the intent used for this packet */
 );
 
+/** Data receive notification callback type*/
+typedef void (*glink_rx_tracer_pkt_notification_cb)
+(
+  glink_handle_type handle,     /* handle for the glink channel */
+  const void        *priv,      /* priv client data passed in glink_open */
+  const void        *pkt_priv,  /* private client data assiciated with the
+                                   rx intent that client queued earlier */
+  const void        *ptr,       /* pointer to the received buffer */
+  size_t            size        /* size of the packet */
+);
+
 /** Vector receive notification callback type*/
 typedef void (*glink_rxv_notification_cb)
 (
@@ -295,54 +312,58 @@
  */
 typedef struct {
   /** string name for the transport to use (Optional)*/
-  const char                    *transport;
+  const char                          *transport;
 
   /** string name for the remote subsystem to which the user wants to
       connect */
-  const char                    *remote_ss;
+  const char                          *remote_ss;
 
   /** string name for the channel */
-  const char                    *name;
+  const char                          *name;
 
   /** bitfield for specifying various options */
-  unsigned                      options;
+  unsigned                            options;
 
   /** Private data for client to maintain context. This data is passed back
       to client in the notification callbacks */
-  const void                    *priv;
+  const void                          *priv;
 
   /** Data receive notification callback. Optional if notify_rxv is provided */
-  glink_rx_notification_cb      notify_rx;
+  glink_rx_notification_cb            notify_rx;
+
+  /** Tracer packet receive notification callback.
+   *  Optional if user doesn't need to use this */
+  glink_rx_tracer_pkt_notification_cb notify_rx_tracer_pkt;
 
   /** Vector receive notification callback. Optional if notify_rx is provided */
-  glink_rxv_notification_cb     notify_rxv;
+  glink_rxv_notification_cb           notify_rxv;
 
   /** Data transmit notification callback */
-  glink_tx_notification_cb      notify_tx_done;
+  glink_tx_notification_cb            notify_tx_done;
 
   /** GLink channel state notification callback */
-  glink_state_notification_cb   notify_state;
+  glink_state_notification_cb         notify_state;
 
   /** Intent request from the remote side. Optional */
-  glink_notify_rx_intent_req_cb notify_rx_intent_req;
+  glink_notify_rx_intent_req_cb       notify_rx_intent_req;
 
   /** New intent arrival from the remote side */
-  glink_notify_rx_intent_cb     notify_rx_intent;
+  glink_notify_rx_intent_cb           notify_rx_intent;
 
   /** Control signal change notification - Invoked when remote side
    *  alters its control signals. Optional */
-  glink_notify_rx_sigs_cb       notify_rx_sigs;
+  glink_notify_rx_sigs_cb             notify_rx_sigs;
 
   /** rx_intent abort notification. This callback would be invoked for
    *  every rx_intent that is queued with GLink core at the time the
    *  remote side or local side decides to close the port. Optional */
-  glink_notify_rx_abort_cb      notify_rx_abort;
+  glink_notify_rx_abort_cb            notify_rx_abort;
 
   /** tx abort notification. This callback would be invoked if client
   *   had queued a tx buffer with glink and it had not been transmitted i.e.
   *   tx_done callback has not been called for this buffer and remote side
   *   or local side closed the port. Optional */
-  glink_notify_tx_abort_cb      notify_tx_abort;
+  glink_notify_tx_abort_cb            notify_tx_abort;
 
 }glink_open_config_type;
 
diff --git a/platform/msm_shared/include/glink_core_if.h b/platform/msm_shared/include/glink_core_if.h
index 040bf31..67cd106 100644
--- a/platform/msm_shared/include/glink_core_if.h
+++ b/platform/msm_shared/include/glink_core_if.h
@@ -57,9 +57,6 @@
 ===========================================================================*/
 typedef struct glink_core_version glink_core_version_type;
 
-struct glink_channel_ctx;
-typedef struct glink_channel_ctx glink_channel_ctx_type;
-
 /**
  * Transport status
  */
@@ -81,45 +78,48 @@
   size_t     pkt_sz;     /* Size of the packet */
   uint32     iid;        /* Intent ID */
   void       *iovec;     /* Pointer to the data buffer to be transmitted */
+  boolean    tracer_pkt;  /* Specify if this intent is for tracer packet */
   glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
   glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
 };
-/** GLink channel states*/
-typedef enum {
-  /** GLink channel state during initialization. No resources have been
-   *  allocated for this channel as neither GLink end has actually opened
-   *  the channel */
-  GLINK_CH_STATE_CLOSED,
 
-  /** GLink channel state when the local side has opened the channel. GLink
-   *  core is waiting for the other end of the channel to open */
-  GLINK_CH_STATE_LOCAL_OPEN,
+/** Context of Tx activity for a transport */
+typedef struct glink_tx_xport_ctx_s {
+  os_event_type event;   /* Event to signal Tx thread */
+  os_cs_type tx_q_cs;    /* Lock to protect Tx queue */
+  smem_list_type tx_q;   /* Tx channel queue */
+} glink_tx_xport_ctx_type;
 
-  /** GLink channel state when it is fully open. This implies that both ends
-   *  of the GLink channel are now open. Data transfer can now take place */
-  GLINK_CH_STATE_OPEN,
+/** G-Link Local channel states */
+typedef enum
+{
+  /** Local G-Link channel is fully closed */
+  GLINK_LOCAL_CH_CLOSED,
 
-  /** GLink channel state when remote side has initiated a OPEN operation. */
-  GLINK_CH_STATE_REMOTE_OPEN,
+  /** Local G-Link channel opened channel and waiting for ACK from remote */
+  GLINK_LOCAL_CH_OPENING,
 
-  /** GLink channel state when remote side has initiated a CLOSE operation.
-   *  Data cannot be transmitted/received any further on this channel */
-  GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE,
+  /** Local G-Link channel is fully opened */
+  GLINK_LOCAL_CH_OPENED,
 
-  /** GLink channel state when the local side has initiated a CLOSE. This
-   *  would be followed by a GLINK_STATE_CLOSE state transition after
-   *  the remote side has acknowledged the CLOSE request */
-   GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE,
+  /** Local G-Link channel closed the channel and waiting for ACK from remote */
+  GLINK_LOCAL_CH_CLOSING
 
-  /** GLink channel state would transition to SLEEP if the underlying
-   *  transport supports low power mode and decides to go into sleep
-   *  due to inactivity for some time or any other reason. */
-  GLINK_CH_STATE_SLEEP,
+}glink_local_state_type;
 
-  /** GLink channel state would transition to AWAKE state when underlying
-   *  transport layer has powered up the hardware */
-  GLINK_CH_STATE_AWAKE
-}glink_ch_state_type;
+/** G-Link Remote channel states */
+typedef enum
+{
+  /** Remote G-Link channel is closed */
+  GLINK_REMOTE_CH_CLOSED,
+
+  /** Remote G-Link channel is opened */
+  GLINK_REMOTE_CH_OPENED,
+
+  /* Glink channel state when SSR is received from remote sub-system */
+  GLINK_REMOTE_CH_SSR_RESET
+
+}glink_remote_state_type;
 
 /** Indicates that transport is now ready to start negotiation using the
  *  v0 configuration. */
@@ -187,14 +187,6 @@
   uint32                  rcid     /* Remote channel ID */
 );
 
-/** Process local state transition */
-typedef void (*ch_state_local_trans_fn)
-(
-  glink_transport_if_type  *if_ptr,  /* Pointer to the interface instance */
-  uint32                   lcid,     /* Local channel ID */
-  glink_ch_state_type      new_state /* New local channel state */
-);
-
 /** Transport invokes this call on receiving remote RX intent */
 typedef void (*rx_cmd_remote_rx_intent_put_fn)
 (
@@ -246,7 +238,7 @@
 (
   glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
   uint32                  rcid,    /* Remote channel ID */
-  boolean                 granted  /* True if RX Intent will be queued, FALSE
+  boolean                 granted  /* True if RX Intent will be queued, false
                                       if request will not be granted. */
 );
 
@@ -292,8 +284,8 @@
   glink_rx_intent_type *intent_ptr      /* Pointer to the intent context */
 );
 
-/** Use remote intent */
-typedef glink_err_type(*use_rm_intent_fn)
+/** Channel submit pkt */
+typedef glink_err_type(*channel_submit_pkt_fn)
 (
   glink_channel_ctx_type *open_ch_ctx,  /* Pointer to the channel context */
   glink_core_tx_pkt_type *pctx,         /* Pointer to the packet context */
@@ -306,10 +298,10 @@
 struct glink_core_xport_ctx
 {
   /* Transport name */
-  char                          xport[32];
+  const char                    *xport;
 
   /* Remote subsystem name */
-  char                          remote_ss[32];
+  const char                    *remote_ss;
 
   /** Keep track of version array index in use */
   const glink_core_version_type *version_array;
@@ -320,6 +312,10 @@
   /* Keeps track of the current status of the transport */
   glink_transport_status_type   status;
 
+  /* critical section to change/access xport status
+   * automically */
+  os_cs_type                    status_cs;
+
   /* Transport's capabilities */
   uint32                        xport_capabilities;
 
@@ -339,6 +335,9 @@
   /* Critical section to protect access to liid allocation */
   os_cs_type                    liid_cs;
 
+  /* Context of Tx activity for a transport */
+  glink_tx_xport_ctx_type       *tx_ctx;
+
   /* channel open config verification */
   verify_open_cfg_fn            verify_open_cfg;
 
@@ -351,8 +350,8 @@
   /* channel receive pkt */
   channel_receive_pkt_fn        channel_receive_pkt;
 
-  /** Use remote intent */
-  use_rm_intent_fn              use_rm_intent;
+  /* channel submit pkt */
+  channel_submit_pkt_fn         channel_submit_pkt;
 };
 
 /**
@@ -381,26 +380,18 @@
    *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
   rx_cmd_ch_remote_open_fn       rx_cmd_ch_remote_open;
 
-
   /** This function is invoked by the transport in response to
    *  glink_transport_if_type:: tx_cmd_ch_open */
   rx_cmd_ch_open_ack_fn          rx_cmd_ch_open_ack;
 
-
   /** This function is invoked by the transport in response to
    *  glink_transport_if_type:: tx_cmd_ch_close */
   rx_cmd_ch_close_ack_fn         rx_cmd_ch_close_ack;
 
-
   /** Remote channel close request; will result in sending
    *  glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
   rx_cmd_ch_remote_close_fn      rx_cmd_ch_remote_close;
 
-
-  /** Process local state transition */
-  ch_state_local_trans_fn        ch_state_local_trans;
-
-
   /** Transport invokes this call on receiving remote RX intent */
   rx_cmd_remote_rx_intent_put_fn rx_cmd_remote_rx_intent_put;
 
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
index 96b0a59..bdd434c 100644
--- a/platform/msm_shared/include/glink_internal.h
+++ b/platform/msm_shared/include/glink_internal.h
@@ -45,7 +45,6 @@
 #include "glink_os_utils.h"
 #include "glink_core_if.h"
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -92,10 +91,18 @@
   GLINK_EVENT_CH_SIG_SET,
   GLINK_EVENT_CH_SIG_L_GET,
   GLINK_EVENT_CH_SIG_R_GET,
+  GLINK_EVENT_CH_NO_MIGRATION,
+  GLINK_EVENT_CH_MIGRATION_IN_PROGRESS,
   GLINK_EVENT_XPORT_INTERNAL,
+  GLINK_EVENT_TRACER_PKT_FAILURE,
+  GLINK_EVENT_TXV_INVALID_BUFFER
 }glink_log_event_type;
 
 typedef struct _glink_channel_intents_type {
+
+  /* Link for a channel in Tx queue */
+  struct _glink_channel_intents_type* next;
+
   /* Critical section to protest access to intent queues */
   os_cs_type                    intent_q_cs;
 
@@ -124,81 +131,91 @@
   /* Read intent being gathered */
   glink_rx_intent_type          *cur_read_intent;
 
+  /* Linked list of Tx packets in the order they where submitted by
+   * the channel owner */
+  smem_list_type                tx_pkt_q;
+
 } glink_channel_intents_type;
 
 struct glink_channel_ctx {
   /* Link needed for use with list APIs.  Must be at the head of the struct */
-  smem_list_link_type           link;
+  smem_list_link_type                 link;
 
   /* Channel name */
-  char                          name[GLINK_CH_NAME_LEN];
+  char                                name[GLINK_CH_NAME_LEN];
 
   /* Local channel ID */
-  uint32                        lcid;
+  uint32                              lcid;
 
   /* Remote Channel ID */
-  uint32                        rcid;
+  uint32                              rcid;
 
-  /* Channel state */
-  glink_ch_state_type           state;
+  /* Local Channel state */
+  glink_local_state_type              local_state;
+
+  /* Remote channel state */
+  glink_remote_state_type             remote_state;
+
+  /* Critical section to protect channel states */
+  os_cs_type                          ch_state_cs;
 
   /* Channel local control signal state */
-  uint32                        local_sigs;
+  uint32                              local_sigs;
 
   /* Channel remote control signal state */
-  uint32                        remote_sigs;
+  uint32                              remote_sigs;
 
   /* Critical section to protect tx operations */
-  os_cs_type                    tx_cs;
+  os_cs_type                          tx_cs;
 
   /* channel intent collection */
-  glink_channel_intents_type    *pintents;
+  glink_channel_intents_type          *pintents;
 
   /* Interface pointer with with this channel is registered */
-  glink_transport_if_type       *if_ptr;
+  glink_transport_if_type             *if_ptr;
 
   /** Private data for client to maintain context. This data is passed back
    * to client in the notification callbacks */
-  const void                    *priv;
+  const void                          *priv;
 
   /** Data receive notification callback */
-  glink_rx_notification_cb      notify_rx;
+  glink_rx_notification_cb            notify_rx;
+
+  /** Tracer Packet data receive notification callback */
+  glink_rx_tracer_pkt_notification_cb notify_rx_tracer_pkt;
 
   /** Vector receive notification callback */
-  glink_rxv_notification_cb      notify_rxv;
+  glink_rxv_notification_cb           notify_rxv;
 
   /** Data transmit notification callback */
-  glink_tx_notification_cb      notify_tx_done;
+  glink_tx_notification_cb            notify_tx_done;
 
   /** GLink channel state notification callback */
-  glink_state_notification_cb   notify_state;
+  glink_state_notification_cb         notify_state;
 
   /** Intent request from the remote side */
-  glink_notify_rx_intent_req_cb notify_rx_intent_req;
+  glink_notify_rx_intent_req_cb       notify_rx_intent_req;
 
   /** New intent arrival from the remote side */
-  glink_notify_rx_intent_cb     notify_rx_intent;
+  glink_notify_rx_intent_cb           notify_rx_intent;
 
   /** Control signal change notification - Invoked when remote side
    *  alters its control signals */
-  glink_notify_rx_sigs_cb       notify_rx_sigs;
+  glink_notify_rx_sigs_cb             notify_rx_sigs;
 
   /** rx_intent abort notification. This callback would be invoked for
   *  every rx_intent that is queued with GLink core at the time the
   *  remote side or local side decides to close the port. Optional */
-  glink_notify_rx_abort_cb      notify_rx_abort;
+  glink_notify_rx_abort_cb            notify_rx_abort;
 
   /** tx abort notification. This callback would be invoked if client
   *   had queued a tx buffer with glink and it had not been transmitted i.e.
   *   tx_done callback has not been called for this buffer and remote side
   *   or local side closed the port. Optional */
-  glink_notify_tx_abort_cb      notify_tx_abort;
+  glink_notify_tx_abort_cb            notify_tx_abort;
 
   /* glink transport if pointer for preferred channel */
-  glink_transport_if_type       *req_if_ptr;
-
-  /* reference count for no of times channel open/close has been called */
-  uint32                        ref_count;
+  glink_transport_if_type             *req_if_ptr;
 
   /* flag to check if channel is marked for deletion
    * This is workaround to prevent channel migration algorithm from finding channel
@@ -207,10 +224,10 @@
    * This may lead to remote side opening channel on neogitated xport from which local side
    * will get remote open again. In this case channel to be closed will be found for negotiation
    * on initial xport again and channel migration algorithm will be triggered(again)  */
-  boolean                       tag_ch_for_close;
+  boolean                             tag_ch_for_close;
 
   /* save glink open config options */
-  uint32 ch_open_options;
+  uint32                              ch_open_options;
 };
 
 
@@ -235,7 +252,6 @@
   void                      *priv;         /* Notification priv ptr */
 } glink_link_notif_data_type;
 
-
 /*===========================================================================
                               GLOBAL DATA DECLARATIONS
 ===========================================================================*/
@@ -411,27 +427,6 @@
 );
 
 /*===========================================================================
-FUNCTION      glink_ch_state_local_trans
-
-DESCRIPTION   Process local state transition
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid      Remote Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_ch_state_local_trans
-(
-  glink_transport_if_type  *if_ptr,  /* Pointer to the interface instance */
-  uint32                   lcid,     /* Local channel ID */
-  glink_ch_state_type      new_state /* New local channel state */
-);
-
-/*===========================================================================
 FUNCTION      glink_rx_put_pkt_ctx
 
 DESCRIPTION   Transport invokes this call to receive a packet fragment (must
@@ -483,25 +478,6 @@
 );
 
 /*===========================================================================
-FUNCTION      glink_tx_resume
-
-DESCRIPTION   If transport was full and could not continue a transmit
-              operation, then it will call this function to notify the core
-              that it is ready to resume transmission.
-
-ARGUMENTS   *if_ptr    Pointer to interface instance; must be unique
-                       for each edge
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_tx_resume
-(
-  glink_transport_if_type *if_ptr /* Pointer to the interface instance */
-);
-
-/*===========================================================================
 FUNCTION      glink_set_core_version
 
 DESCRIPTION   Sets the core version used by the transport; called after
@@ -534,7 +510,7 @@
 
 ARGUMENTS     *cfg_ptr   - Pointer to channel context
 
-RETURN VALUE  True if fully opened, FALSE otherwise.
+RETURN VALUE  True if fully opened, false otherwise.
 
 SIDE EFFECTS  None
 ===========================================================================*/
@@ -746,41 +722,36 @@
 );
 
 /*===========================================================================
-FUNCTION      glinki_add_ch_to_xport
-
-DESCRIPTION   Add remote/local channel context to xport open channel queue
-
-ARGUMENTS     *if_ptr            - Pointer to xport if on which channel is to
-                                   be opened
-              *req_if_ptr        - Pointer to xport if on which channel
-			                       actually wants to open
-              *ch_ctx            - channel context
-              **allocated_ch_ctx - Pointer to channel context pointer
-              local_open         - flag to determine if channel is opened
-			                       locally or remotely
-              migration state    - flag to identify whether channel migration
-			                       negotiation is done
-                                   TRUE - negotiation is not complete
-                                   FALSE - negotiation is complete.
-								   channel is being opened on same xport as negotiated
-              prio               - negotiated xport priority
-			                       (used to send priority via remote_open_ack to
-								    remote side)
-              *tx_pkt            - Pointer to the packet context to remove
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
+  FUNCTION      glinki_add_ch_to_xport
 ===========================================================================*/
+/**
+ * Add remote/local channel context to xport open channel queue
+ *
+ * @param[in]    if_ptr            Pointer to xport if on which channel is to
+ *                                 be opened
+ * @param[in]    req_if_ptr        Pointer to xport if on which channel
+ *                                 actually wants to open
+ * @param[in]    ch_ctx            channel context
+ * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
+ * @param[in]    local_open        flag to determine if channel is opened
+ *                                 locally or remotely
+ * @param[in]    prio              negotiated xport priority
+ *                                 (used to send priority via remote_open_ack to
+ *                                  remote side)
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
 glink_err_type glinki_add_ch_to_xport
 (
   glink_transport_if_type  *if_ptr,
   glink_transport_if_type  *req_if_ptr,
   glink_channel_ctx_type   *ch_ctx,
-  glink_channel_ctx_type   **allocated_ch_ctx,
+  glink_channel_ctx_type  **allocated_ch_ctx,
   unsigned int              local_open,
-  boolean                  migration_state,
-  glink_xport_priority     prio
+  glink_xport_priority      prio
 );
 
 void glink_mem_log
@@ -811,6 +782,20 @@
 void glink_core_setup(glink_transport_if_type *if_ptr);
 
 /*===========================================================================
+FUNCTION      glink_core_get_default_interface
+===========================================================================*/
+/**
+
+  Provides default core interface.
+
+  @return     Pointer to the default core interface.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_default_interface(void);
+
+/*===========================================================================
 FUNCTION      glink_core_setup_full_xport
 ===========================================================================*/
 /**
diff --git a/platform/msm_shared/include/glink_os_utils.h b/platform/msm_shared/include/glink_os_utils.h
index e0a1613..ad8f0d1 100644
--- a/platform/msm_shared/include/glink_os_utils.h
+++ b/platform/msm_shared/include/glink_os_utils.h
@@ -175,13 +175,12 @@
 
   @param[in] s1     String 1
   @param[in] s2     String 2
-  @param[in] size   The maximum number of characters to compare
 
   @return
   0 if strings are identical (up to size characters), non-zero otherwise
 */
 /*==========================================================================*/
-long glink_os_string_compare( const char *s1, const char *s2, uint32_t size );
+long glink_os_string_compare( const char *s1, const char *s2 );
 
 /*===========================================================================
   FUNCTION  glink_os_copy_mem
diff --git a/platform/msm_shared/include/glink_transport_if.h b/platform/msm_shared/include/glink_transport_if.h
index da9e2bd..84056b0 100644
--- a/platform/msm_shared/include/glink_transport_if.h
+++ b/platform/msm_shared/include/glink_transport_if.h
@@ -51,9 +51,13 @@
 /* GLink transport capability bit definitions */
 /* Whether transport supports signalling */
 #define GLINK_CAPABILITY_SIG_SUPPORT 0x00000001
+
 /* Intentless mode of operation */
 #define GLINK_CAPABILITY_INTENTLESS  0x00000002
 
+/* Tracer packet support */
+#define GLINK_CAPABILITY_TRACER_PKT  0x00000004
+
 /*===========================================================================
                       TYPE DECLARATIONS
 ===========================================================================*/
@@ -70,6 +74,9 @@
 struct glink_rx_intent;
 typedef struct glink_rx_intent      glink_rx_intent_type;
 
+struct glink_channel_ctx;
+typedef struct glink_channel_ctx glink_channel_ctx_type;
+
 /* Priority of transports registered with glink */
 typedef enum {
   GLINK_XPORT_SMEM = 100,
@@ -81,13 +88,17 @@
 } glink_xport_priority;
 
 /** Glink core -> Xport pkt type definition */
-typedef struct {
+typedef struct glink_core_tx_pkt_s {
+  struct glink_core_tx_pkt_s *next; /* pointer to the next packet in list */
+
   void       *data;      /* Pointer to the data buffer to be transmitted */
   const void *pkt_priv;  /* Per packet private data */
+  uint32     cid;        /* Local channel ID being used to transmit data */
   uint32     iid;        /* Remote intent ID being used to transmit data */
   size_t     size;       /* Size of data buffer */
   size_t     size_remaining; /* Size left to transmit */
   void       *iovec;      /* Pointer to the data buffer to be transmitted */
+  boolean    tracer_pkt;  /* specify if this intent is for tracer packet */
   glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
   glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
 }glink_core_tx_pkt_type;
@@ -317,7 +328,7 @@
    *  channel */
   tx_fn                              tx;
 
-   /** Send request to the remote to queue more rx intents */
+  /** Send request to the remote to queue more rx intents */
   tx_cmd_rx_intent_req_fn            tx_cmd_rx_intent_req;
 
   /** Send ACK to the remote side's request to queue more rx intents */
diff --git a/platform/msm_shared/include/mipi_dsi.h b/platform/msm_shared/include/mipi_dsi.h
index b4d81a4..81c4612 100644
--- a/platform/msm_shared/include/mipi_dsi.h
+++ b/platform/msm_shared/include/mipi_dsi.h
@@ -201,6 +201,13 @@
 	int wait;
 };
 
+struct mipi_dsi_i2c_cmd {
+	uint8_t i2c_addr;
+	uint8_t reg;
+	uint8_t val;
+	int sleep_in_ms;
+};
+
 struct mipi_dsi_panel_config {
 	char mode;
 	char num_of_lanes;
diff --git a/platform/msm_shared/include/mipi_dsi_i2c.h b/platform/msm_shared/include/mipi_dsi_i2c.h
new file mode 100644
index 0000000..b67b977
--- /dev/null
+++ b/platform/msm_shared/include/mipi_dsi_i2c.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation. nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef __MIPI_DSI_I2C_H__
+#define __MIPI_DSI_I2C_H__
+
+#include <stdint.h>
+
+int mipi_dsi_i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *buf);
+int mipi_dsi_i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t val);
+int mipi_dsi_i2c_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
+int mipi_dsi_i2c_device_init();
+
+#endif /* __MIPI_DSI_I2C_H__ */
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index ff99ba3..7a3b014 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -267,6 +267,13 @@
 	unsigned long max_link_clk;
 };
 
+struct dsi2HDMI_panel_info {
+	struct mipi_dsi_i2c_cmd *dsi_tg_i2c_cmd;
+	struct mipi_dsi_i2c_cmd *dsi_setup_cfg_i2c_cmd;
+	int num_of_tg_i2c_cmds;
+	int num_of_cfg_i2c_cmds;
+};
+
 enum lvds_mode {
 	LVDS_SINGLE_CHANNEL_MODE,
 	LVDS_DUAL_CHANNEL_MODE,
@@ -315,6 +322,7 @@
 	struct lvds_panel_info lvds;
 	struct hdmi_panel_info hdmi;
 	struct edp_panel_info edp;
+	struct dsi2HDMI_panel_info adv7533;
 
 	struct dfps_info dfps;
 
@@ -345,6 +353,7 @@
 	int (*post_power_func)(int enable);
 	int (*pre_init_func)(void);
 	int (*update_panel_info) (void);
+	int (*dsi2HDMI_config) (struct msm_panel_info *);
 };
 
 #endif
diff --git a/platform/msm_shared/include/xport_rpm.h b/platform/msm_shared/include/xport_rpm.h
index 2566172..8282766 100644
--- a/platform/msm_shared/include/xport_rpm.h
+++ b/platform/msm_shared/include/xport_rpm.h
@@ -39,7 +39,7 @@
                         INCLUDE FILES
 ===========================================================================*/
 #include "glink_transport_if.h"
-#include <glink.h>
+
 /*===========================================================================
                       MACRO DECLARATIONS
 ===========================================================================*/
@@ -67,10 +67,6 @@
 
 #define XPORT_RPM_GET_CHANNEL_ID(c)   (((c) >> 16) & 0xFFFF)
 #define XPORT_RPM_SET_CHANNEL_ID(cid) (((cid) << 16) & 0xFFFF0000)
-#define XPORT_RPM_GET_STR_LEN(c)      (((c) >> 16) & 0xFFFF)
-#define XPORT_RPM_SET_STR_LEN(c)      (((c) << 16) & 0xFFFF0000)
-#define XPORT_RPM_GET_PRIO(c)         ((c) & 0xFFFF)
-#define XPORT_RPM_SET_PRIO(c)         ((c) & 0xFFFF)
 
 #define XPORT_RPM_GET_VERSION(c) (((c) >> 16) & 0xFFFF)
 #define XPORT_RPM_SET_VERSION(v) (((v) << 16) & 0xFFFF0000)
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index baed08b..d67b5c8 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -107,12 +107,18 @@
 
 	if (mdss_mdp_rev == MDSS_MDP_HW_REV_110)
 		return 0xB0020;
+	else if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
+		return 0xB0000;
 	else
 		return 0xC8020;
 }
 
 void mdp_clk_gating_ctrl(void)
 {
+	uint32_t mdss_mdp_rev = readl(MDP_HW_REV);
+	if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
+		return;
+
 	writel(0x40000000, MDP_CLK_CTRL0);
 	udelay(20);
 	writel(0x40000040, MDP_CLK_CTRL0);
@@ -277,8 +283,10 @@
 
 static void mdss_vbif_setup()
 {
-	int access_secure = restore_secure_cfg(SECURE_DEVICE_MDSS);
 	uint32_t mdp_hw_rev = readl(MDP_HW_REV);
+	int access_secure = false;
+	if (!MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev, MDSS_MDP_HW_REV_107))
+		access_secure = restore_secure_cfg(SECURE_DEVICE_MDSS);
 
 	if (!access_secure) {
 		dprintf(SPEW, "MDSS VBIF registers unlocked by TZ.\n");
@@ -464,6 +472,7 @@
 	uint32_t hsync_start_x, hsync_end_x;
 	uint32_t display_hctl, hsync_ctl, display_vstart, display_vend;
 	uint32_t adjust_xres = 0;
+	uint32_t upper = 0, lower = 0;
 
 	struct lcdc_panel_info *lcdc = NULL;
 	struct intf_timing_params itp = {0};
@@ -479,8 +488,15 @@
 	if (pinfo->lcdc.split_display) {
 		adjust_xres /= 2;
 		if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) {
-			writel(BIT(8), MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL);
-			writel(BIT(8), MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL);
+			if (pinfo->lcdc.pipe_swap) {
+				lower |= BIT(4);
+				upper |= BIT(8);
+			} else {
+				lower |= BIT(8);
+				upper |= BIT(4);
+			}
+			writel(lower, MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL);
+			writel(upper, MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL);
 			writel(0x1, MDP_REG_SPLIT_DISPLAY_EN);
 		}
 	}
diff --git a/platform/msm_shared/mipi_dsi_i2c.c b/platform/msm_shared/mipi_dsi_i2c.c
new file mode 100644
index 0000000..b8b690e
--- /dev/null
+++ b/platform/msm_shared/mipi_dsi_i2c.c
@@ -0,0 +1,99 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <mipi_dsi_i2c.h>
+#include <blsp_qup.h>
+#include <i2c_qup.h>
+#include <gsbi.h>
+#include <err.h>
+#include <debug.h>
+
+#define I2C_CLK_FREQ     100000
+#define I2C_SRC_CLK_FREQ 50000000
+
+static struct qup_i2c_dev *i2c_dev;
+
+int mipi_dsi_i2c_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
+{
+	if (!buf)
+		return ERR_INVALID_ARGS;
+
+	if(!i2c_dev)
+		return ERR_NOT_VALID;
+
+	struct i2c_msg rd_buf[] = {
+		{addr, I2C_M_WR, 1, &reg},
+		{addr, I2C_M_RD, len, buf}
+	};
+
+	int err = qup_i2c_xfer(i2c_dev, rd_buf, 2);
+	if (err < 0) {
+		dprintf(CRITICAL, "Read reg %x failed\n", reg);
+		return err;
+	}
+
+	return NO_ERROR;
+}
+
+int mipi_dsi_i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *buf)
+{
+	if (!buf)
+		return ERR_INVALID_ARGS;
+
+	return mipi_dsi_i2c_read(addr, reg, buf, 1);
+}
+
+int mipi_dsi_i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t val)
+{
+	if (!i2c_dev)
+		return ERR_NOT_VALID;
+
+	unsigned char buf[2] = {reg, val};
+	struct i2c_msg msg_buf[] = {
+		{addr, I2C_M_WR, 2, buf},
+	};
+
+	int err = qup_i2c_xfer(i2c_dev, msg_buf, 1);
+	if (err < 0) {
+		dprintf(CRITICAL, "Write reg %x failed\n", reg);
+		return err;
+	}
+	return NO_ERROR;
+}
+
+int mipi_dsi_i2c_device_init()
+{
+	i2c_dev = qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_3,
+				I2C_CLK_FREQ, I2C_SRC_CLK_FREQ);
+	if(!i2c_dev) {
+		dprintf(CRITICAL, "mipi_dsi_i2c_device_init() failed\n");
+		return ERR_NOT_VALID;
+	}
+	return NO_ERROR;
+}
diff --git a/platform/msm_shared/qmp_usb30_phy.c b/platform/msm_shared/qmp_usb30_phy.c
index a2c21cf..54a8831 100644
--- a/platform/msm_shared/qmp_usb30_phy.c
+++ b/platform/msm_shared/qmp_usb30_phy.c
@@ -47,17 +47,33 @@
 
 static bool hsonly_mode;
 
-struct qmp_reg qmp_settings[] =
+/* Override values for QMP 2.0 V1 devices */
+struct qmp_reg qmp_override_pll_rev2[] =
+{
+	{0x124, 0x1C}, /* USB3PHY_QSERDES_COM_VCO_TUNE_CTRL */
+	{0x12C, 0x3F}, /* USB3PHY_QSERDES_COM_VCO_TUNE1_MODE0 */
+	{0x130, 0x01}, /* USB3PHY_QSERDES_COM_VCO_TUNE2_MODE0 */
+	{0x6c4, 0x13}, /* USB3_PHY_FLL_CNTRL2 */
+};
+
+/* QMP settings for 2.0 QMP V2 HW */
+struct qmp_reg qmp_settings_rev2[] =
 {
 	{0xAC, 0x14}, /* QSERDES_COM_SYSCLK_EN_SEL */
 	{0x34, 0x08}, /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */
 	{0x174, 0x30}, /* QSERDES_COM_CLK_SELECT */
-	{0x3C, 0x06}, /* QSERDES_COM_SYS_CLK_CTRL */
-	{0xb4, 0x00}, /* QSERDES_COM_RESETSM_CNTRL */
-	{0xb8, 0x08}, /* QSERDES_COM_RESETSM_CNTRL2 */
 	{0x194, 0x06}, /* QSERDES_COM_CMN_CONFIG */
 	{0x19c, 0x01}, /* QSERDES_COM_SVS_MODE_CLK_SEL */
 	{0x178, 0x01}, /* QSERDES_COM_HSCLK_SEL */
+	{0x70, 0x0F}, /* USB3PHY_QSERDES_COM_BG_TRIM */
+	{0x48, 0x0F}, /* USB3PHY_QSERDES_COM_PLL_IVCO */
+	{0x3C, 0x04}, /* QSERDES_COM_SYS_CLK_CTRL */
+
+	/* Res_code Settings */
+	{0xC4, 0x15}, /* USB3PHY_QSERDES_COM_RESCODE_DIV_NUM */
+	{0x1B8, 0x1F}, /* QSERDES_COM_CMN_MISC2 */
+
+	/* PLL & Loop filter settings */
 	{0xd0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */
 	{0xdc, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
 	{0xe0, 0x55}, /* QSERDES_COM_DIV_FRAC_START2_MODE0 */
@@ -66,20 +82,17 @@
 	{0x84, 0x16}, /* QSERDES_COM_PLL_RCTRL_MODE0 */
 	{0x90, 0x28}, /* QSERDES_COM_PLL_CCTRL_MODE0 */
 	{0x108, 0x80}, /* QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */
-	{0x10c, 0x00}, /* QSERDES_COM_INTEGLOOP_GAIN1_MODE0 */
-	{0x124, 0x1c}, /* QSERDES_COM_VCO_TUNE_CTRL */
-	{0x12c, 0x3f}, /* QSERDES_COM_VCO_TUNE1_MODE0 */
-	{0x130, 0x01}, /* QSERDES_COM_VCO_TUNE2_MODE0 */
-	{0x184, 0x0a}, /* QSERDES_COM_CORECLK_DIV */
+	{0x124, 0x00}, /* QSERDES_COM_VCO_TUNE_CTRL */
 	{0x4c, 0x15}, /* QSERDES_COM_LOCK_CMP1_MODE0 */
 	{0x50, 0x34}, /* QSERDES_COM_LOCK_CMP2_MODE0 */
 	{0x54, 0x00}, /* QSERDES_COM_LOCK_CMP3_MODE0 */
-	{0xc8, 0x00}, /* QSERDES_COM_LOCK_CMP_EN */
 	{0x18c, 0x00}, /* QSERDES_COM_CORE_CLK_EN */
-	{0xc4, 0x15}, /*QSERDES_COM_RESCODE_DIV_NUM */
 	{0xcc, 0x00}, /* QSERDES_COM_LOCK_CMP_CFG */
+	{0x0C, 0x0A}, /* QSERDES_COM_BG_TIMER */
 	{0x128, 0x00}, /* QSERDES_COM_VCO_TUNE_MAP */
 	{0xc, 0x0a}, /* QSERDES_COM_BG_TIMER */
+
+	/* SSC settings */
 	{0x10, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */
 	{0x1c, 0x31}, /* QSERDES_COM_SSC_PER1 */
 	{0x20, 0x01}, /* QSERDES_COM_SSC_PER2 */
@@ -87,31 +100,38 @@
 	{0x18, 0x00}, /* QSERDES_COM_SSC_ADJ_PER2 */
 	{0x24, 0xde}, /* QSERDES_COM_SSC_STEP_SIZE1 */
 	{0x28, 0x07}, /* QSERDES_COM_SSC_STEP_SIZE2 */
+
+	/* Rx Settings */
 	{0x440, 0x0b}, /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */
-	{0x4d8, 0x03}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
-	{0x4dc, 0x6c}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
-	{0x70, 0xf}, /* QSERDES_COM_BG_TRIM */
-	{0x48, 0xf}, /* QSERDES_COM_PLL_IVCO */
-	{0x4e0, 0xb8}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
+	{0x41C, 0x04}, /* QSERDES_RX_UCDR_SO_GAIN */
+	{0x4d8, 0x02}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
+	{0x4dc, 0x4c}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
+	{0x4e0, 0xbb}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
 	{0x508, 0x77}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */
 	{0x50c, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */
-	{0x514, 0x04}, /* QSERDES_RX_SIGDET_CNTRL */
+	{0x514, 0x03}, /* QSERDES_RX_SIGDET_CNTRL */
 	{0x518, 0x1b}, /* QSERDES_RX_SIGDET_LVL */
 	{0x51c, 0x16}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */
+
+	/* Tx settings */
 	{0x268, 0x45}, /* QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN */
 	{0x2ac, 0x12}, /* QSERDES_TX_RCV_DETECT_LVL_2 */
+	{0x294, 0x06}, /* QSERDES_TX_LANE_MODE */
+
+	/* FLL settings */
 	{0x6c4, 0x03}, /* USB3_PHY_FLL_CNTRL2 */
 	{0x6c0, 0x02}, /* USB3_PHY_FLL_CNTRL1 */
 	{0x6c8, 0x09}, /* USB3_PHY_FLL_CNT_VAL_L */
 	{0x6cc, 0x42}, /* USB3_PHY_FLL_CNT_VAL_H_TOL */
 	{0x6d0, 0x85}, /* USB3_PHY_FLL_MAN_CODE */
-	{0x294, 0x02}, /* QSERDES_TX_LANE_MODE */
+
+	/* Lock Det Settings */
 	{0x680, 0xd1}, /* USB3_PHY_LOCK_DETECT_CONFIG1 */
 	{0x684, 0x1f}, /* USB3_PHY_LOCK_DETECT_CONFIG2 */
 	{0x688, 0x47}, /* USB3_PHY_LOCK_DETECT_CONFIG3 */
 	{0x664, 0x08}, /* USB3_PHY_POWER_STATE_CONFIG2 */
-	{0x600, 0x00}, /* USB3_PHY_SW_RESET */
 	{0x608, 0x03}, /* USB3_PHY_START_CONTROL */
+	{0x600, 0x00}, /* USB3_PHY_SW_RESET */
 };
 
 __WEAK uint32_t target_override_pll()
@@ -241,9 +261,16 @@
 
 	if (rev_id >= 0x20000000)
 	{
-		qmp_reg_size = sizeof(qmp_settings) / sizeof(struct qmp_reg);
+		qmp_reg_size = sizeof(qmp_settings_rev2) / sizeof(struct qmp_reg);
 		for (i = 0 ; i < qmp_reg_size; i++)
-			writel(qmp_settings[i].val, QMP_PHY_BASE + qmp_settings[i].off);
+			writel(qmp_settings_rev2[i].val, QMP_PHY_BASE + qmp_settings_rev2[i].off);
+
+		if (target_override_pll())
+		{
+			qmp_reg_size = sizeof(qmp_override_pll_rev2) / sizeof(struct qmp_reg);
+			for (i = 0 ; i < qmp_reg_size; i++)
+				writel(qmp_override_pll_rev2[i].val, QMP_PHY_BASE + qmp_override_pll_rev2[i].off);
+		}
 	}
 	else
 	{
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index a098c00..dd024f8 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -199,7 +199,8 @@
 		$(LOCAL_DIR)/crypto_hash.o \
 		$(LOCAL_DIR)/crypto5_eng.o \
 		$(LOCAL_DIR)/crypto5_wrapper.o \
-		$(LOCAL_DIR)/i2c_qup.o
+		$(LOCAL_DIR)/i2c_qup.o \
+		$(LOCAL_DIR)/mipi_dsi_i2c.o
 
 endif
 
@@ -503,6 +504,7 @@
 endif
 
 ifeq ($(PLATFORM),msm8996)
+DEFINES += DISPLAY_TYPE_MDSS=1
 	OBJS += $(LOCAL_DIR)/qtimer.o \
 			$(LOCAL_DIR)/qtimer_mmap.o \
 			$(LOCAL_DIR)/interrupts.o \
@@ -525,7 +527,12 @@
 			$(LOCAL_DIR)/image_verify.o \
 			$(LOCAL_DIR)/crypto_hash.o \
 			$(LOCAL_DIR)/crypto5_eng.o \
-			$(LOCAL_DIR)/crypto5_wrapper.o
+			$(LOCAL_DIR)/crypto5_wrapper.o \
+			$(LOCAL_DIR)/mdp5.o \
+			$(LOCAL_DIR)/display.o \
+			$(LOCAL_DIR)/mipi_dsi.o \
+			$(LOCAL_DIR)/mipi_dsi_phy.o \
+			$(LOCAL_DIR)/mipi_dsi_autopll_thulium.o
 endif
 
 ifeq ($(ENABLE_UFS_SUPPORT), 1)
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 664c0ae..2a8ef25 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -21,6 +21,7 @@
 ENABLE_PARTIAL_GOODS_SUPPORT := 1
 ENABLE_RPMB_SUPPORT := 1
 ENABLE_GLINK_SUPPORT := 1
+ENABLE_PWM_SUPPORT := true
 
 DEFINES +=VIRTIO=1
 
diff --git a/target/apq8084/target_display.c b/target/apq8084/target_display.c
index 20e4d03..9ae3ea1 100755
--- a/target/apq8084/target_display.c
+++ b/target/apq8084/target_display.c
@@ -261,6 +261,16 @@
 	return NO_ERROR;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 int target_display_pre_on()
 {
 	writel(0x000000FA, MDP_QOS_REMAPPER_CLASS_0);
diff --git a/target/mdm9615/atags.c b/target/mdm9615/atags.c
index 8d02808..76f46b3 100755
--- a/target/mdm9615/atags.c
+++ b/target/mdm9615/atags.c
@@ -63,7 +63,7 @@
 
 				*ptr++ = 4;
 				*ptr++ = 0x54410002;
-				*ptr++ = SIZE_23M;
+				*ptr++ = (SIZE_23M-SIZE_1M);
 				*ptr++ = ram_ptable.parts[i].start + SIZE_88M;
 
 				if(ram_ptable.parts[i].size == 0x10000000) {
diff --git a/target/msm8226/target_display.c b/target/msm8226/target_display.c
index fe2e6d5..0bc1173 100755
--- a/target/msm8226/target_display.c
+++ b/target/msm8226/target_display.c
@@ -390,6 +390,16 @@
 	return ret;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
 {
 	return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
diff --git a/target/msm8610/target_display.c b/target/msm8610/target_display.c
index f87b2ed..1213bd3 100755
--- a/target/msm8610/target_display.c
+++ b/target/msm8610/target_display.c
@@ -183,6 +183,16 @@
 	return 0;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
 {
 	return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
diff --git a/target/msm8909/target_display.c b/target/msm8909/target_display.c
index e949547..085dc00 100755
--- a/target/msm8909/target_display.c
+++ b/target/msm8909/target_display.c
@@ -232,6 +232,16 @@
 	return NO_ERROR;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
 {
 	return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
diff --git a/target/msm8916/include/target/display.h b/target/msm8916/include/target/display.h
index 27b4a5d..e27432f 100644
--- a/target/msm8916/include/target/display.h
+++ b/target/msm8916/include/target/display.h
@@ -99,6 +99,10 @@
   "msmgpio", 22, 3, 1, 0, 1
 };
 
+static struct gpio_pin dsi2HDMI_switch_gpio = {
+  "msmgpio", 32, 3, 1, 0, 1
+};
+
 /*---------------------------------------------------------------------------*/
 /* Target Physical configuration                                             */
 /*---------------------------------------------------------------------------*/
@@ -179,6 +183,8 @@
 	R61318_HD_VIDEO_PANEL,
 	R63417_1080P_VIDEO_PANEL,
 	JDI_A216_FHD_VIDEO_PANEL,
+	ADV7533_1080P_VIDEO_PANEL,
+	ADV7533_720P_VIDEO_PANEL,
 	UNKNOWN_PANEL
 };
 
diff --git a/target/msm8916/oem_panel.c b/target/msm8916/oem_panel.c
index 4c51fcb..0562017 100644
--- a/target/msm8916/oem_panel.c
+++ b/target/msm8916/oem_panel.c
@@ -34,6 +34,7 @@
 #include <board.h>
 #include <mipi_dsi.h>
 #include <target/display.h>
+#include <mipi_dsi_i2c.h>
 
 #include "include/panel.h"
 #include "panel_display.h"
@@ -58,6 +59,8 @@
 #include "include/panel_r61318_hd_video.h"
 #include "include/panel_r63417_1080p_video.h"
 #include "include/panel_jdi_a216_fhd_video.h"
+#include "include/panel_adv7533_1080p60.h"
+#include "include/panel_adv7533_720p60.h"
 
 #define DISPLAY_MAX_PANEL_DETECTION 2
 #define OTM8019A_FWVGA_VIDEO_PANEL_ON_DELAY 50
@@ -97,6 +100,8 @@
 	{"r61318_hd_video", R61318_HD_VIDEO_PANEL},
 	{"r63417_1080p_video", R63417_1080P_VIDEO_PANEL},
 	{"jdi_a216_fhd_video", JDI_A216_FHD_VIDEO_PANEL},
+	{"adv7533_1080p_video", ADV7533_1080P_VIDEO_PANEL},
+	{"adv7533_720p_video", ADV7533_720P_VIDEO_PANEL},
 };
 
 static uint32_t panel_id;
@@ -554,6 +559,41 @@
 		memcpy(phy_db->timing,
 				jdi_a216_fhd_video_timings, TIMING_SIZE);
 		break;
+	case ADV7533_1080P_VIDEO_PANEL:
+		panelstruct->paneldata	  = &adv7533_1080p_video_panel_data;
+		panelstruct->panelres	  = &adv7533_1080p_video_panel_res;
+		panelstruct->color		  = &adv7533_1080p_video_color;
+		panelstruct->videopanel   = &adv7533_1080p_video_video_panel;
+		panelstruct->commandpanel = &adv7533_1080p_video_command_panel;
+		panelstruct->state		  = &adv7533_1080p_video_state;
+		panelstruct->laneconfig   = &adv7533_1080p_video_lane_config;
+		panelstruct->paneltiminginfo
+					= &adv7533_1080p_video_timing_info;
+		pinfo->adv7533.dsi_tg_i2c_cmd = &adv7533_1080p_tg_i2c_command;
+		pinfo->adv7533.num_of_tg_i2c_cmds = ADV7533_1080P_TG_COMMANDS;
+		pinfo->adv7533.dsi_setup_cfg_i2c_cmd = &adv7533_1080p_common_cfg;
+		pinfo->adv7533.num_of_cfg_i2c_cmds = ADV7533_1080P_CONFIG_COMMANDS;
+		memcpy(phy_db->timing,
+					adv7533_1080p_video_timings, TIMING_SIZE);
+		break;
+
+	case ADV7533_720P_VIDEO_PANEL:
+		panelstruct->paneldata    = &adv7533_720p_video_panel_data;
+		panelstruct->panelres     = &adv7533_720p_video_panel_res;
+		panelstruct->color        = &adv7533_720p_video_color;
+		panelstruct->videopanel   = &adv7533_720p_video_video_panel;
+		panelstruct->commandpanel = &adv7533_720p_video_command_panel;
+		panelstruct->state        = &adv7533_720p_video_state;
+		panelstruct->laneconfig   = &adv7533_720p_video_lane_config;
+		panelstruct->paneltiminginfo
+					= &adv7533_720p_video_timing_info;
+		pinfo->adv7533.dsi_tg_i2c_cmd = &adv7533_720p_tg_i2c_command;
+		pinfo->adv7533.num_of_tg_i2c_cmds = ADV7533_720P_TG_COMMANDS;
+		pinfo->adv7533.dsi_setup_cfg_i2c_cmd = &adv7533_720p_common_cfg;
+		pinfo->adv7533.num_of_cfg_i2c_cmds = ADV7533_720P_CONFIG_COMMANDS;
+		memcpy(phy_db->timing,
+					adv7533_720p_video_timings, TIMING_SIZE);
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -584,6 +624,7 @@
 	uint32_t hw_subtype = board_hardware_subtype();
 	int32_t panel_override_id;
 	uint32_t target_id, plat_hw_ver_major;
+	uint8_t rev = 0;
 
 	if (panel_name) {
 		panel_override_id = panel_name_to_id(supp_panels,
@@ -702,6 +743,22 @@
 			}
 		}
 		break;
+	case HW_PLATFORM_SBC:
+		if (platform_is_apq8016()) {
+			/* Set Switch GPIO to DSI2HDMI mode */
+			target_set_switch_gpio(1);
+			/* ADV7533 DSI to HDMI Bridge Chip Connected */
+			mipi_dsi_i2c_device_init();
+			/* Read ADV Chip ID */
+			if (!mipi_dsi_i2c_read_byte(ADV7533_MAIN, 0x00, &rev)) {
+				dprintf(INFO, "ADV7533 Rev ID: 0x%x\n",rev);
+			} else {
+				dprintf(CRITICAL, "error reading Rev ID from bridge chip\n");
+				return PANEL_TYPE_UNKNOWN;
+			}
+			panel_id = ADV7533_720P_VIDEO_PANEL;
+		}
+		break;
 	default:
 		dprintf(CRITICAL, "Display not enabled for %d HW type\n",
 			hw_id);
diff --git a/target/msm8916/target_display.c b/target/msm8916/target_display.c
index 42693d6..56ee921 100644
--- a/target/msm8916/target_display.c
+++ b/target/msm8916/target_display.c
@@ -42,6 +42,7 @@
 #include <target/display.h>
 #include <i2c_qup.h>
 #include <blsp_qup.h>
+#include <mipi_dsi_i2c.h>
 
 #include "include/panel.h"
 #include "include/display_resource.h"
@@ -298,6 +299,51 @@
 	return 0;
 }
 
+static int dsi2HDMI_i2c_write_regs(struct mipi_dsi_i2c_cmd *cfg, int size)
+{
+	int ret = NO_ERROR;
+	int i;
+
+	if (!cfg)
+		return ERR_INVALID_ARGS;
+
+	for (i = 0; i < size; i++) {
+		ret = mipi_dsi_i2c_write_byte(cfg[i].i2c_addr, cfg[i].reg,
+			cfg[i].val);
+		if (ret) {
+			dprintf(CRITICAL, "mipi_dsi reg writes failed\n");
+			goto w_regs_fail;
+		}
+		if (cfg[i].sleep_in_ms) {
+			udelay(cfg[i].sleep_in_ms*1000);
+		}
+	}
+w_regs_fail:
+	return ret;
+}
+
+int target_display_dsi2hdmi_config(struct msm_panel_info *pinfo)
+{
+	int ret = NO_ERROR;
+
+	if (!pinfo)
+		return ERR_INVALID_ARGS;
+
+	/*
+	 * If dsi to HDMI bridge chip connected then
+	 * send I2c commands to the chip
+	 */
+	if (pinfo->adv7533.dsi_setup_cfg_i2c_cmd)
+		ret = dsi2HDMI_i2c_write_regs(pinfo->adv7533.dsi_setup_cfg_i2c_cmd,
+					pinfo->adv7533.num_of_cfg_i2c_cmds);
+
+	if (pinfo->adv7533.dsi_tg_i2c_cmd)
+		ret = dsi2HDMI_i2c_write_regs(pinfo->adv7533.dsi_tg_i2c_cmd,
+					pinfo->adv7533.num_of_tg_i2c_cmds);
+
+	return ret;
+}
+
 static int target_panel_reset_skuh(uint8_t enable)
 {
 	int ret = NO_ERROR;
@@ -501,6 +547,16 @@
 	return ret;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
 {
 	/*
@@ -515,6 +571,20 @@
 	return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
 }
 
+void target_set_switch_gpio(int enable_dsi2HdmiBridge)
+{
+	gpio_tlmm_config(dsi2HDMI_switch_gpio.pin_id, 0,
+				dsi2HDMI_switch_gpio.pin_direction,
+				dsi2HDMI_switch_gpio.pin_pull,
+				dsi2HDMI_switch_gpio.pin_strength,
+				dsi2HDMI_switch_gpio.pin_state);
+	gpio_set_dir(enable_gpio.pin_id, 2);
+	if (enable_dsi2HdmiBridge)
+		gpio_set_dir(enable_gpio.pin_id, 0); /* DSI2HDMI Bridge */
+	else
+		gpio_set_dir(enable_gpio.pin_id, 2); /* Normal DSI operation */
+}
+
 void target_display_init(const char *panel_name)
 {
 	uint32_t panel_loop = 0;
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 9a86cd9..2a908d6 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -362,6 +362,16 @@
 	qpnp_wled_init(&config);
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
 {
 
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index 73319ea..eae18f0 100755
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -263,6 +263,16 @@
 	return NO_ERROR;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 /* Pull DISP_RST_N high to get panel out of reset */
 int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
 					struct msm_panel_info *pinfo)
diff --git a/target/msm8994/target_display.c b/target/msm8994/target_display.c
index 1779ea5..bb3fa2f 100644
--- a/target/msm8994/target_display.c
+++ b/target/msm8994/target_display.c
@@ -576,6 +576,16 @@
 	return NO_ERROR;
 }
 
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+	memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+	memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+	return NO_ERROR;
+}
+
 int target_display_get_base_offset(uint32_t base)
 {
 	if(platform_is_msm8992()) {
diff --git a/target/msm8996/include/target/display.h b/target/msm8996/include/target/display.h
new file mode 100644
index 0000000..eddc0c8
--- /dev/null
+++ b/target/msm8996/include/target/display.h
@@ -0,0 +1,96 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _TARGET_DISPLAY_H
+#define _TARGET_DISPLAY_H
+
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include <display_resource.h>
+
+/*---------------------------------------------------------------------------*/
+/* Target Physical configuration                                             */
+/*---------------------------------------------------------------------------*/
+
+static const uint32_t panel_strength_ctrl[] = {
+  0xFF, 0x06,
+  0xFF, 0x06,
+  0xFF, 0x06,
+  0xFF, 0x06,
+  0xFF, 0x00
+};
+
+static const uint32_t panel_regulator_settings[] = {
+  0x1d, 0x1d, 0x1d, 0x1d, 0x1d
+};
+
+static const char panel_lane_config[] = {
+  0x00, 0x00, 0x10, 0x0f,
+  0x00, 0x00, 0x10, 0x0f,
+  0x00, 0x00, 0x10, 0x0f,
+  0x00, 0x00, 0x10, 0x0f,
+  0x00, 0x00, 0x10, 0x8f,
+};
+
+static const char panel_bist_ctrl[] = { };
+
+static const uint32_t panel_physical_ctrl[] = { };
+/*---------------------------------------------------------------------------*/
+/* Other Configuration                                                       */
+/*---------------------------------------------------------------------------*/
+#define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
+
+#define MIPI_FB_ADDR  0x82400000
+
+#define MIPI_HSYNC_PULSE_WIDTH       16
+#define MIPI_HSYNC_BACK_PORCH_DCLK   32
+#define MIPI_HSYNC_FRONT_PORCH_DCLK  76
+
+#define MIPI_VSYNC_PULSE_WIDTH       2
+#define MIPI_VSYNC_BACK_PORCH_LINES  2
+#define MIPI_VSYNC_FRONT_PORCH_LINES 4
+
+#define PWM_BL_LPG_CHAN_ID           4	/* lpg_out<3> */
+
+#define HDMI_PANEL_NAME              "hdmi"
+#define HDMI_CONTROLLER_STRING       "hdmi:0"
+
+/*---------------------------------------------------------------------------*/
+/* Functions		                                                     */
+/*---------------------------------------------------------------------------*/
+int target_display_pre_on();
+int target_display_pre_off();
+int target_display_post_on();
+int target_display_post_off();
+int target_cont_splash_screen();
+int target_display_get_base_offset(uint32_t base);
+void target_force_cont_splash_disable(uint8_t override);
+uint8_t target_panel_auto_detect_enabled();
+
+#endif
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 57695d8..6667314 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -282,6 +282,33 @@
 	/* This is filled from board.c */
 }
 
+static uint8_t splash_override;
+/* Returns 1 if target supports continuous splash screen. */
+int target_cont_splash_screen()
+{
+	uint8_t splash_screen = 0;
+	if(!splash_override) {
+		switch(board_hardware_id())
+		{
+			case HW_PLATFORM_SURF:
+			case HW_PLATFORM_MTP:
+			case HW_PLATFORM_FLUID:
+				dprintf(SPEW, "Target_cont_splash=1\n");
+				splash_screen = 1;
+				break;
+			default:
+				dprintf(SPEW, "Target_cont_splash=0\n");
+				splash_screen = 0;
+		}
+	}
+	return splash_screen;
+}
+
+void target_force_cont_splash_disable(uint8_t override)
+{
+        splash_override = override;
+}
+
 /* Detect the modem type */
 void target_baseband_detect(struct board_data *board)
 {
@@ -385,7 +412,10 @@
 
 uint32_t target_override_pll()
 {
-	return 1;
+	if (board_soc_version() >= 0x20000)
+		return 0;
+	else
+		return 1;
 }
 
 crypto_engine_type board_ce_type(void)
diff --git a/target/msm8996/oem_panel.c b/target/msm8996/oem_panel.c
new file mode 100644
index 0000000..4e86448
--- /dev/null
+++ b/target/msm8996/oem_panel.c
@@ -0,0 +1,288 @@
+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <string.h>
+#include <err.h>
+#include <smem.h>
+#include <msm_panel.h>
+#include <board.h>
+#include <mipi_dsi.h>
+#include <qtimer.h>
+#include <platform.h>
+
+#include "include/panel.h"
+#include "target/display.h"
+#include "panel_display.h"
+#include <mipi_dsi.h>
+
+/*---------------------------------------------------------------------------*/
+/* GCDB Panel Database                                                       */
+/*---------------------------------------------------------------------------*/
+#include "include/panel_nt35597_wqxga_dualdsi_video.h"
+#include "include/panel_sharp_wqxga_dualdsi_video.h"
+#include "include/panel_jdi_qhd_dualdsi_video.h"
+#include "include/panel_jdi_qhd_dualdsi_cmd.h"
+
+/*---------------------------------------------------------------------------*/
+/* static panel selection variable                                           */
+/*---------------------------------------------------------------------------*/
+enum {
+	NT35597_WQXGA_DUALDSI_VIDEO_PANEL,
+	SHARP_WQXGA_DUALDSI_VIDEO_PANEL,
+	JDI_QHD_DUALDSI_VIDEO_PANEL,
+	JDI_QHD_DUALDSI_CMD_PANEL,
+	UNKNOWN_PANEL
+};
+
+/*
+ * The list of panels that are supported on this target.
+ * Any panel in this list can be selected using fastboot oem command.
+ */
+static struct panel_list supp_panels[] = {
+	{"nt35597_wqxga_dualdsi_video", NT35597_WQXGA_DUALDSI_VIDEO_PANEL},
+	{"sharp_wqxga_dualdsi_video", SHARP_WQXGA_DUALDSI_VIDEO_PANEL},
+	{"jdi_qhd_dualdsi_video", JDI_QHD_DUALDSI_VIDEO_PANEL},
+	{"jdi_qhd_dualdsi_cmd", JDI_QHD_DUALDSI_CMD_PANEL},
+};
+
+static uint32_t panel_id;
+
+int oem_panel_rotation()
+{
+	return NO_ERROR;
+}
+
+int oem_panel_on()
+{
+	if (panel_id == JDI_QHD_DUALDSI_CMD_PANEL) {
+		/* needs extra delay to avoid unexpected artifacts */
+		mdelay(JDI_QHD_DUALDSI_CMD_PANEL_ON_DELAY);
+
+	}
+	return NO_ERROR;
+}
+
+int oem_panel_off()
+{
+	return NO_ERROR;
+}
+
+static bool init_panel_data(struct panel_struct *panelstruct,
+			struct msm_panel_info *pinfo,
+			struct mdss_dsi_phy_ctrl *phy_db)
+{
+	int pan_type;
+
+	switch (panel_id) {
+	case SHARP_WQXGA_DUALDSI_VIDEO_PANEL:
+		pan_type = PANEL_TYPE_DSI;
+		pinfo->lcd_reg_en = 0;
+		panelstruct->paneldata    = &sharp_wqxga_dualdsi_video_panel_data;
+		panelstruct->paneldata->panel_node_id =
+			"qcom,mdss_dsi_sharp_wqxga_video_0";
+		panelstruct->paneldata->slave_panel_node_id =
+			"qcom,mdss_dsi_sharp_wqxga_video_1";
+		panelstruct->paneldata->panel_operating_mode = 11;
+		panelstruct->paneldata->panel_with_enable_gpio = 0;
+
+		panelstruct->panelres     = &sharp_wqxga_dualdsi_video_panel_res;
+		panelstruct->color        = &sharp_wqxga_dualdsi_video_color;
+		panelstruct->videopanel   = &sharp_wqxga_dualdsi_video_video_panel;
+		panelstruct->commandpanel = &sharp_wqxga_dualdsi_video_command_panel;
+		panelstruct->state        = &sharp_wqxga_dualdsi_video_state;
+		panelstruct->laneconfig   = &sharp_wqxga_dualdsi_video_lane_config;
+		panelstruct->paneltiminginfo
+			= &sharp_wqxga_dualdsi_video_timing_info;
+		panelstruct->panelresetseq
+					 = &sharp_wqxga_dualdsi_video_reset_seq;
+		panelstruct->backlightinfo = &sharp_wqxga_dualdsi_video_backlight;
+
+		pinfo->labibb = &sharp_wqxga_dualdsi_video_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= sharp_wqxga_dualdsi_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= SHARP_WQXGA_DUALDSI_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= sharp_wqxga_dualdsi_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= SHARP_WQXGA_DUALDSI_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			sharp_wqxga_dualdsi_thulium_video_timings,
+			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		pinfo->mipi.tx_eot_append = true;
+		break;
+	case NT35597_WQXGA_DUALDSI_VIDEO_PANEL:
+		pan_type = PANEL_TYPE_DSI;
+		pinfo->lcd_reg_en = 0;
+		panelstruct->paneldata    = &nt35597_wqxga_dualdsi_video_panel_data;
+		panelstruct->paneldata->panel_operating_mode = 11;
+		panelstruct->paneldata->panel_with_enable_gpio = 0;
+
+		panelstruct->panelres     = &nt35597_wqxga_dualdsi_video_panel_res;
+		panelstruct->color        = &nt35597_wqxga_dualdsi_video_color;
+		panelstruct->videopanel   = &nt35597_wqxga_dualdsi_video_video_panel;
+		panelstruct->commandpanel = &nt35597_wqxga_dualdsi_video_command_panel;
+		panelstruct->state        = &nt35597_wqxga_dualdsi_video_state;
+		panelstruct->laneconfig   = &nt35597_wqxga_dualdsi_video_lane_config;
+		panelstruct->paneltiminginfo
+			= &nt35597_wqxga_dualdsi_video_timing_info;
+		panelstruct->panelresetseq
+					 = &nt35597_wqxga_dualdsi_video_reset_seq;
+		panelstruct->backlightinfo = &nt35597_wqxga_dualdsi_video_backlight;
+
+		pinfo->labibb = &nt35597_wqxga_dualdsi_video_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= nt35597_wqxga_dualdsi_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= NT35597_WQXGA_DUALDSI_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= nt35597_wqxga_dualdsi_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= NT35597_WQXGA_DUALDSI_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			nt35597_wqxga_dualdsi_thulium_video_timings,
+			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		pinfo->mipi.tx_eot_append = true;
+		break;
+	case JDI_QHD_DUALDSI_VIDEO_PANEL:
+		pan_type = PANEL_TYPE_DSI;
+		pinfo->lcd_reg_en = 1;
+		panelstruct->paneldata->panel_node_id =
+			"qcom,dsi_jdi_qhd_video_0";
+		panelstruct->paneldata->slave_panel_node_id =
+			"qcom,dsi_jdi_qhd_video_1";
+		panelstruct->paneldata    = &jdi_qhd_dualdsi_video_panel_data;
+
+		panelstruct->panelres     = &jdi_qhd_dualdsi_video_panel_res;
+		panelstruct->color        = &jdi_qhd_dualdsi_video_color;
+		panelstruct->videopanel   = &jdi_qhd_dualdsi_video_video_panel;
+		panelstruct->commandpanel = &jdi_qhd_dualdsi_video_command_panel;
+		panelstruct->state        = &jdi_qhd_dualdsi_video_state;
+		panelstruct->laneconfig   = &jdi_qhd_dualdsi_video_lane_config;
+		panelstruct->paneltiminginfo
+			= &jdi_qhd_dualdsi_video_timing_info;
+		panelstruct->panelresetseq
+					 = &jdi_qhd_dualdsi_video_reset_seq;
+		panelstruct->backlightinfo = &jdi_qhd_dualdsi_video_backlight;
+		pinfo->mipi.panel_on_cmds
+			= jdi_qhd_dualdsi_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= JDI_QHD_DUALDSI_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= jdi_qhd_dualdsi_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= JDI_QHD_DUALDSI_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			jdi_qhd_dualdsi_thulium_cmd_timings,
+			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		break;
+	case JDI_QHD_DUALDSI_CMD_PANEL:
+		pan_type = PANEL_TYPE_DSI;
+		pinfo->lcd_reg_en = 1;
+		panelstruct->paneldata    = &jdi_qhd_dualdsi_cmd_panel_data;
+		panelstruct->paneldata->panel_node_id =
+			"qcom,mdss_dsi_jdi_qhd_dualmipi0_cmd";
+		panelstruct->paneldata->slave_panel_node_id =
+			"qcom,mdss_dsi_jdi_qhd_dualmipi1_cmd";
+
+		panelstruct->panelres     = &jdi_qhd_dualdsi_cmd_panel_res;
+		panelstruct->color        = &jdi_qhd_dualdsi_cmd_color;
+		panelstruct->videopanel   = &jdi_qhd_dualdsi_cmd_video_panel;
+		panelstruct->commandpanel = &jdi_qhd_dualdsi_cmd_command_panel;
+		panelstruct->state        = &jdi_qhd_dualdsi_cmd_state;
+		panelstruct->laneconfig   = &jdi_qhd_dualdsi_cmd_lane_config;
+		panelstruct->paneltiminginfo
+			= &jdi_qhd_dualdsi_cmd_timing_info;
+		panelstruct->panelresetseq
+					 = &jdi_qhd_dualdsi_cmd_reset_seq;
+		panelstruct->backlightinfo = &jdi_qhd_dualdsi_cmd_backlight;
+		pinfo->mipi.panel_on_cmds
+			= jdi_qhd_dualdsi_cmd_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= JDI_QHD_DUALDSI_CMD_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= jdi_qhd_dualdsi_cmd_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= JDI_QHD_DUALDSI_CMD_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			jdi_qhd_dualdsi_thulium_video_timings,
+			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		break;
+	default:
+	case UNKNOWN_PANEL:
+		pan_type = PANEL_TYPE_UNKNOWN;
+		break;
+	}
+	return pan_type;
+}
+
+int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
+			struct msm_panel_info *pinfo,
+			struct mdss_dsi_phy_ctrl *phy_db)
+{
+	uint32_t hw_id = board_hardware_id();
+	int32_t panel_override_id;
+
+	phy_db->pll_type = DSI_PLL_TYPE_THULIUM;
+
+	if (panel_name) {
+		panel_override_id = panel_name_to_id(supp_panels,
+				ARRAY_SIZE(supp_panels), panel_name);
+
+		if (panel_override_id < 0) {
+			dprintf(CRITICAL, "Not able to search the panel:%s\n",
+					 panel_name + strspn(panel_name, " "));
+		} else if (panel_override_id < UNKNOWN_PANEL) {
+			/* panel override using fastboot oem command */
+			panel_id = panel_override_id;
+
+			dprintf(INFO, "OEM panel override:%s\n",
+					panel_name + strspn(panel_name, " "));
+			goto panel_init;
+		}
+	}
+
+	switch (hw_id) {
+	case HW_PLATFORM_MTP:
+	case HW_PLATFORM_FLUID:
+	case HW_PLATFORM_SURF:
+		panel_id = SHARP_WQXGA_DUALDSI_VIDEO_PANEL;
+		break;
+	default:
+		dprintf(CRITICAL, "Display not enabled for %d HW type\n"
+					, hw_id);
+		return PANEL_TYPE_UNKNOWN;
+	}
+
+panel_init:
+	return init_panel_data(panelstruct, pinfo, phy_db);
+}
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index 2326ff0..2544635 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -1,6 +1,7 @@
 LOCAL_DIR := $(GET_LOCAL_DIR)
 
 INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
+INCLUDES += -I$(LK_TOP_DIR)/dev/gcdb/display -I$(LK_TOP_DIR)/dev/gcdb/display/include
 
 PLATFORM := msm8996
 
@@ -14,13 +15,16 @@
 KERNEL_ADDR  := 0x80000000
 KERNEL_SIZE  := 62
 
-DEFINES += DISPLAY_SPLASH_SCREEN=0
+DEFINES += DISPLAY_SPLASH_SCREEN=1
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
 
 MODULES += \
 	dev/keys \
 	dev/pmic/pm8x41 \
+	dev/qpnp_wled \
+	dev/qpnp_led \
+	dev/gcdb/display \
 	lib/ptable \
 	lib/libfdt
 
@@ -38,7 +42,9 @@
 
 OBJS += \
 	$(LOCAL_DIR)/init.o \
-	$(LOCAL_DIR)/meminfo.o
+	$(LOCAL_DIR)/meminfo.o \
+	$(LOCAL_DIR)/target_display.o \
+	$(LOCAL_DIR)/oem_panel.o \
 
 ifeq ($(ENABLE_GLINK_SUPPORT),1)
 OBJS += \
diff --git a/target/msm8996/target_display.c b/target/msm8996/target_display.c
new file mode 100644
index 0000000..f9f3a5b
--- /dev/null
+++ b/target/msm8996/target_display.c
@@ -0,0 +1,515 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <string.h>
+#include <smem.h>
+#include <err.h>
+#include <msm_panel.h>
+#include <mipi_dsi.h>
+#include <pm8x41.h>
+#include <pm8x41_wled.h>
+#include <qpnp_wled.h>
+#include <board.h>
+#include <mdp5.h>
+#include <endian.h>
+#include <regulator.h>
+#include <qtimer.h>
+#include <arch/defines.h>
+#include <platform/gpio.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+#include <target/display.h>
+#include <mipi_dsi_autopll_thulium.h>
+
+#include "include/panel.h"
+#include "include/display_resource.h"
+#include "gcdb_display.h"
+
+#define GPIO_STATE_LOW 0
+#define GPIO_STATE_HIGH 2
+#define RESET_GPIO_SEQ_LEN 3
+
+#define PWM_DUTY_US 13
+#define PWM_PERIOD_US 27
+#define PMIC_WLED_SLAVE_ID 3
+#define PMIC_MPP_SLAVE_ID 2
+
+#define MAX_POLL_READS 15
+#define POLL_TIMEOUT_US 1000
+
+#define STRENGTH_SIZE_IN_BYTES_8996	10
+#define REGULATOR_SIZE_IN_BYTES_8996	5
+#define LANE_SIZE_IN_BYTES_8996		20
+
+/*---------------------------------------------------------------------------*/
+/* GPIO configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct gpio_pin reset_gpio = {
+  "msmgpio", 8, 3, 1, 0, 1
+};
+
+static struct gpio_pin lcd_reg_en = {	/* boost regulator */
+  "pmi8994_gpios", 8, 3, 1, 0, 1
+};
+
+static struct gpio_pin bklt_gpio = {	/* lcd_bklt_reg_en */
+  "pm8994_gpios", 14, 3, 1, 0, 1
+};
+
+static uint32_t thulium_dsi_pll_lock_status(uint32_t pll_base, uint32_t off,
+	uint32_t bit)
+{
+	uint32_t cnt, status;
+
+	/* check pll lock first */
+	for (cnt = 0; cnt < MAX_POLL_READS; cnt++) {
+		status = readl(pll_base + off);
+		dprintf(SPEW, "%s: pll_base=%x cnt=%d status=%x\n",
+				__func__, pll_base, cnt, status);
+		status &= BIT(bit); /* bit 5 */
+		if (status)
+			break;
+		udelay(POLL_TIMEOUT_US);
+	}
+
+	return status;
+}
+
+static uint32_t thulium_dsi_pll_enable_seq(uint32_t phy_base, uint32_t pll_base)
+{
+	uint32_t pll_locked;
+
+	writel(0x01, phy_base + 0x48);
+	dmb();
+
+	pll_locked = thulium_dsi_pll_lock_status(pll_base, 0xcc, 5);
+	if (pll_locked)
+		pll_locked = thulium_dsi_pll_lock_status(pll_base, 0xcc, 0);
+
+	if (!pll_locked)
+		dprintf(ERROR, "%s: DSI PLL lock failed\n", __func__);
+	else
+		dprintf(SPEW, "%s: DSI PLL lock Success\n", __func__);
+
+	return  pll_locked;
+}
+
+static int thulium_wled_backlight_ctrl(uint8_t enable)
+{
+	qpnp_wled_enable_backlight(enable);
+	qpnp_ibb_enable(enable);
+	return NO_ERROR;
+}
+
+static int thulium_pwm_backlight_ctrl(uint8_t enable)
+{
+	uint8_t slave_id = 3; /* lpg at pmi */
+
+        if (enable) {
+                /* lpg channel 4 */
+
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
+		mdelay(100);
+
+		 /* LPG_VALUE_LSB, duty cycle = 0x80/0x200 = 1/4 */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x44, 0x80);
+		/* LPG_VALUE_MSB */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x45, 0x00);
+		/* LPG_PWM_SYNC */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x47, 0x01);
+
+		 /* LPG_PWM_SIZE_CLK, */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x41, 0x13);
+		 /* LPG_PWM_FREQ_PREDIV */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x42, 0x02);
+		 /* LPG_PWM_TYPE_CONFIG */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x43, 0x20);
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x04);
+
+		 /* SEC_ACCESS */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xD0, 0xA5);
+		 /* DTEST4, OUT_HI */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xE5, 0x01);
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0xA4);
+        } else {
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
+        }
+
+        return NO_ERROR;
+}
+
+static void lcd_reg_enable(void)
+{
+	uint8_t slave_id = 2;	/* gpio at pmi */
+
+	struct pm8x41_gpio gpio = {
+                .direction = PM_GPIO_DIR_OUT,
+                .function = PM_GPIO_FUNC_HIGH,
+                .vin_sel = 2,   /* VIN_2 */
+                .output_buffer = PM_GPIO_OUT_CMOS,
+                .out_strength = PM_GPIO_OUT_DRIVE_MED,
+        };
+
+        pm8x41_gpio_config_sid(slave_id, lcd_reg_en.pin_id, &gpio);
+	pm8x41_gpio_set_sid(slave_id, lcd_reg_en.pin_id, 1);
+}
+
+static void lcd_reg_disable(void)
+{
+	uint8_t slave_id = 2;	/* gpio at pmi */
+
+	pm8x41_gpio_set_sid(slave_id, lcd_reg_en.pin_id, 0);
+}
+
+static void lcd_bklt_reg_enable(void)
+{
+       struct pm8x41_gpio gpio = {
+                .direction = PM_GPIO_DIR_OUT,
+                .function = PM_GPIO_FUNC_HIGH,
+                .vin_sel = 2,   /* VIN_2 */
+                .output_buffer = PM_GPIO_OUT_CMOS,
+                .out_strength = PM_GPIO_OUT_DRIVE_LOW,
+        };
+
+        pm8x41_gpio_config(bklt_gpio.pin_id, &gpio);
+	pm8x41_gpio_set(bklt_gpio.pin_id, 1);
+}
+
+static void lcd_bklt_reg_disable(void)
+{
+	pm8x41_gpio_set(bklt_gpio.pin_id, 0);
+}
+
+int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
+{
+	uint32_t ret = NO_ERROR;
+	struct pm8x41_mpp mpp;
+	int rc;
+
+	if (!bl) {
+		dprintf(CRITICAL, "backlight structure is not available\n");
+		return ERR_INVALID_ARGS;
+	}
+
+	switch (bl->bl_interface_type) {
+	case BL_WLED:
+		/* Enable MPP4 */
+		pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
+	        mpp.base = PM8x41_MMP4_BASE;
+		mpp.vin = MPP_VIN2;
+		if (enable) {
+			pm_pwm_enable(false);
+			rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
+			if (rc < 0) {
+				mpp.mode = MPP_HIGH;
+			} else {
+				mpp.mode = MPP_DTEST1;
+				pm_pwm_enable(true);
+			}
+			pm8x41_config_output_mpp(&mpp);
+			pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+		} else {
+			pm_pwm_enable(false);
+			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+		}
+		/* Need delay before power on regulators */
+		mdelay(20);
+		/* Enable WLED backlight control */
+		ret = thulium_wled_backlight_ctrl(enable);
+		break;
+	case BL_PWM:
+		/* Enable MPP1 */
+		pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
+	        mpp.base = PM8x41_MMP1_BASE;
+		mpp.vin = MPP_VIN2;
+		mpp.mode = MPP_DTEST4;
+		if (enable) {
+			pm8x41_config_output_mpp(&mpp);
+			pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+		} else {
+			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+		}
+		/* Need delay before power on regulators */
+		mdelay(20);
+		ret = thulium_pwm_backlight_ctrl(enable);
+		break;
+	default:
+		dprintf(CRITICAL, "backlight type:%d not supported\n",
+						bl->bl_interface_type);
+		return ERR_NOT_SUPPORTED;
+	}
+
+	return ret;
+}
+
+int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
+{
+	uint32_t flags;
+	uint32_t ret = NO_ERROR;
+	uint32_t board_version = board_soc_version();
+
+	if (pinfo->dest == DISPLAY_2) {
+		flags = MMSS_DSI_CLKS_FLAG_DSI1;
+		if (pinfo->mipi.dual_dsi)
+			flags |= MMSS_DSI_CLKS_FLAG_DSI0;
+	} else {
+		flags = MMSS_DSI_CLKS_FLAG_DSI0;
+		if (pinfo->mipi.dual_dsi)
+			flags |= MMSS_DSI_CLKS_FLAG_DSI1;
+	}
+
+	if (!enable) {
+		/* stop pll */
+		writel(0x0, pinfo->mipi.phy_base + 0x48);
+		dmb();
+
+		mmss_dsi_clock_disable(flags);
+		goto clks_disable;
+	}
+
+	if (board_version == 0x20000 || board_version == 0x20001)
+		video_gdsc_enable();
+	mmss_gdsc_enable();
+	mmss_bus_clock_enable();
+	mdp_clock_enable();
+	mdss_dsi_auto_pll_thulium_config(pinfo);
+
+	if (!thulium_dsi_pll_enable_seq(pinfo->mipi.phy_base,
+		pinfo->mipi.pll_base)) {
+		ret = ERROR;
+		dprintf(CRITICAL, "PLL failed to lock!\n");
+		goto clks_disable;
+	}
+	mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, flags);
+	return NO_ERROR;
+
+clks_disable:
+	mdp_clock_disable();
+	mmss_bus_clock_disable();
+	mmss_gdsc_disable();
+	if (board_version == 0x20000 || board_version == 0x20001)
+		video_gdsc_disable();
+
+	return ret;
+}
+
+int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
+					struct msm_panel_info *pinfo)
+{
+	uint32_t i = 0;
+
+	if (enable) {
+		gpio_tlmm_config(reset_gpio.pin_id, 0,
+				reset_gpio.pin_direction, reset_gpio.pin_pull,
+				reset_gpio.pin_strength, reset_gpio.pin_state);
+		/* reset */
+		for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
+			if (resetseq->pin_state[i] == GPIO_STATE_LOW)
+				gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
+			else
+				gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
+			mdelay(resetseq->sleep[i]);
+		}
+		lcd_bklt_reg_enable();
+	} else {
+		lcd_bklt_reg_disable();
+		gpio_set(reset_gpio.pin_id, 0);
+	}
+
+	return NO_ERROR;
+}
+
+static void wled_init(struct msm_panel_info *pinfo)
+{
+	struct qpnp_wled_config_data config = {0};
+	struct labibb_desc *labibb;
+	int display_type = 0;
+
+	labibb = pinfo->labibb;
+
+	if (labibb)
+		display_type = labibb->amoled_panel;
+
+	config.display_type = display_type;
+	config.lab_init_volt = 4600000;	/* fixed, see pmi register */
+	config.ibb_init_volt = 1400000;	/* fixed, see pmi register */
+
+	if (labibb && labibb->force_config) {
+		config.lab_min_volt = labibb->lab_min_volt;
+		config.lab_max_volt = labibb->lab_max_volt;
+		config.ibb_min_volt = labibb->ibb_min_volt;
+		config.ibb_max_volt = labibb->ibb_max_volt;
+		config.pwr_up_delay = labibb->pwr_up_delay;
+		config.pwr_down_delay = labibb->pwr_down_delay;
+		config.ibb_discharge_en = labibb->ibb_discharge_en;
+	} else {
+		/* default */
+		config.pwr_up_delay = 3;
+		config.pwr_down_delay =  3;
+		config.ibb_discharge_en = 1;
+		if (display_type) {	/* amoled */
+			config.lab_min_volt = 4600000;
+			config.lab_max_volt = 4600000;
+			config.ibb_min_volt = 4000000;
+			config.ibb_max_volt = 4000000;
+		} else { /* lcd */
+			config.lab_min_volt = 5500000;
+			config.lab_max_volt = 5500000;
+			config.ibb_min_volt = 5500000;
+			config.ibb_max_volt = 5500000;
+		}
+	}
+
+	dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d %d %d\n", __func__,
+		config.display_type,
+		config.lab_min_volt, config.lab_max_volt,
+		config.ibb_min_volt, config.ibb_max_volt,
+		config.lab_init_volt, config.ibb_init_volt,
+		config.pwr_up_delay, config.pwr_down_delay,
+		config.ibb_discharge_en);
+
+
+	/* QPNP WLED init for display backlight */
+	pm8x41_wled_config_slave_id(PMIC_WLED_SLAVE_ID);
+
+	qpnp_wled_init(&config);
+}
+
+int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
+{
+	uint32_t val = BIT(1) | BIT(13) | BIT(27);
+
+	if (enable) {
+		regulator_enable(val);
+		mdelay(10);
+		wled_init(pinfo);
+		qpnp_ibb_enable(true);	/* +5V and -5V */
+		mdelay(50);
+
+		if (pinfo->lcd_reg_en)
+			lcd_reg_enable();
+	} else {
+		if (pinfo->lcd_reg_en)
+			lcd_reg_disable();
+
+		regulator_disable(val);
+	}
+
+	return NO_ERROR;
+}
+
+int target_display_pre_on()
+{
+	writel(0xC0000CCC, MDP_CLK_CTRL0);
+	writel(0xC0000CCC, MDP_CLK_CTRL1);
+	writel(0x00CCCCCC, MDP_CLK_CTRL2);
+	writel(0x000000CC, MDP_CLK_CTRL6);
+	writel(0x0CCCC0C0, MDP_CLK_CTRL3);
+	writel(0xCCCCC0C0, MDP_CLK_CTRL4);
+	writel(0xCCCCC0C0, MDP_CLK_CTRL5);
+	writel(0x00CCC000, MDP_CLK_CTRL7);
+
+	return NO_ERROR;
+}
+
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE_IN_BYTES_8996 *
+		sizeof(uint32_t));
+	memcpy(phy_db->regulator, panel_regulator_settings,
+		REGULATOR_SIZE_IN_BYTES_8996 * sizeof(uint32_t));
+	memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE_IN_BYTES_8996);
+	return NO_ERROR;
+}
+
+
+bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
+{
+	int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
+	bool ret = true;
+
+	panel_name += strspn(panel_name, " ");
+
+	if (!strcmp(panel_name, HDMI_PANEL_NAME)) {
+		if (buf_size < (prefix_string_len + LK_OVERRIDE_PANEL_LEN +
+				strlen(HDMI_CONTROLLER_STRING))) {
+			dprintf(CRITICAL, "command line argument is greater than buffer size\n");
+			return false;
+		}
+
+		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
+		buf_size -= prefix_string_len;
+		strlcat(pbuf, LK_OVERRIDE_PANEL, buf_size);
+		buf_size -= LK_OVERRIDE_PANEL_LEN;
+		strlcat(pbuf, HDMI_CONTROLLER_STRING, buf_size);
+	} else {
+		ret = gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
+	}
+
+	return ret;
+}
+
+void target_display_init(const char *panel_name)
+{
+	char cont_splash = '\0';
+
+	set_panel_cmd_string(panel_name, &cont_splash);
+	panel_name += strspn(panel_name, " ");
+	if (!strcmp(panel_name, NO_PANEL_CONFIG)
+		|| !strcmp(panel_name, SIM_VIDEO_PANEL)
+		|| !strcmp(panel_name, SIM_DUALDSI_VIDEO_PANEL)
+		|| !strcmp(panel_name, SIM_CMD_PANEL)
+		|| !strcmp(panel_name, SIM_DUALDSI_CMD_PANEL)) {
+		dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
+			panel_name);
+		return;
+	} else if (!strcmp(panel_name, HDMI_PANEL_NAME)) {
+		return;
+	}
+
+	if (gcdb_display_init(panel_name, MDP_REV_50, (void *)MIPI_FB_ADDR)) {
+		target_force_cont_splash_disable(true);
+		msm_display_off();
+	}
+
+	if (cont_splash == '0') {
+		dprintf(INFO, "Forcing continuous splash disable\n");
+		target_force_cont_splash_disable(true);
+	}
+}
+
+void target_display_shutdown(void)
+{
+	gcdb_display_shutdown();
+}
diff --git a/target/target_display.c b/target/target_display.c
index fb96638..6904825 100644
--- a/target/target_display.c
+++ b/target/target_display.c
@@ -78,6 +78,11 @@
 	return;
 }
 
+__WEAK int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+	return 0;
+}
+
 __WEAK int target_edp_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
 {
 	return 0;
@@ -121,3 +126,8 @@
 {
 	return 0;
 }
+
+__WEAK int target_display_dsi2hdmi_config(struct msm_panel_info *pinfo)
+{
+	return 0;
+}