Merge "target: msm8909: add support for panel simulation"
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 7e12dfa..60b97b0 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -44,20 +44,17 @@
 #define DIP_ENCRYPT 0
 #define DIP_DECRYPT 1
 
-static int mdtp_tzbsp_get_provisioned_fuse();
-static int mdtp_tzbsp_set_provisioned_fuse();
-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);
-
-unsigned block_size = 0;
+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);
 
 /********************************************************************************/
 
 /* Read the DIP from EMMC */
-static int read_DIP(DIP_t* dip)
+static int read_DIP(DIP_t *dip)
 {
 	unsigned long long ptn = 0;
 	uint32_t actual_partition_size;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	int index = INVALID_PTN;
 
@@ -85,10 +82,11 @@
 }
 
 /* Store the DIP into the EMMC */
-static int write_DIP(DIP_t* dip)
+static int write_DIP(DIP_t *dip)
 {
 	unsigned long long ptn = 0;
 	uint32_t partition_size;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	int index = INVALID_PTN;
 
@@ -121,8 +119,8 @@
 /* Provision the DIP by storing the default DIP into the EMMC */
 static void provision_DIP()
 {
-	DIP_t* enc_dip;
-	DIP_t* dec_dip;
+	DIP_t *enc_dip;
+	DIP_t *dec_dip;
 	int ret;
 
 	enc_dip = malloc(sizeof(DIP_t));
@@ -171,13 +169,13 @@
 }
 
 /* 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, uint32_t size, DIP_hash_table_entry_t *hash_table)
 {
-	SHA256_CTX sha256_ctx;
 	unsigned char digest[32]={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);
 
 	dprintf(INFO, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
@@ -193,19 +191,17 @@
 		return -1;
 	}
 
-	SHA256_Init(&sha256_ctx);
-
 	if (mmc_read(ptn, (void *)buf, actual_partition_size))
 	{
 		dprintf(CRITICAL, "mdtp: verify_partition__single_hash: %s: mmc_read() fail.\n", name);
 		return -1;
 	}
 
-	SHA256_Update(&sha256_ctx, buf, size);
+	/* calculating the hash value using HW crypto */
+	target_crypto_init_params();
+	hash_find(buf, size, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
 
-	SHA256_Final(digest, &sha256_ctx);
-
-	if (memcmp(digest, hash_table->hash, HASH_LEN))
+	if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
 	{
 		dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: Failed partition hash verification\n", name);
 
@@ -218,14 +214,13 @@
 }
 
 /* Validate a hash table calculated per block of a given partition */
-static int verify_partition_block_hash(char* name,
+static int verify_partition_block_hash(char *name,
 								uint32_t size,
 								uint32_t total_num_blocks,
 								uint32_t verify_num_blocks,
-								DIP_hash_table_entry_t* hash_table,
+								DIP_hash_table_entry_t *hash_table,
 							    uint8_t *force_verify_block)
 {
-	SHA256_CTX sha256_ctx;
 	unsigned char digest[32]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
@@ -246,6 +241,9 @@
 		return -1;
 	}
 
+	/* initiating parameters for hash calculation using HW crypto */
+	target_crypto_init_params();
+
 	while (MDTP_FWLOCK_BLOCK_SIZE * block_num < size)
 	{
 		if (*force_verify_block == 0)
@@ -261,8 +259,6 @@
 			}
 		}
 
-		SHA256_Init(&sha256_ctx);
-
 		if ((size - (MDTP_FWLOCK_BLOCK_SIZE * block_num) <  MDTP_FWLOCK_BLOCK_SIZE))
 		{
 			bytes_to_read = size - (MDTP_FWLOCK_BLOCK_SIZE * block_num);
@@ -277,12 +273,10 @@
 			return -1;
 		}
 
-		SHA256_Update(&sha256_ctx, buf, bytes_to_read);
-		SHA256_Update(&sha256_ctx, &block_num, sizeof(block_num));
+		/* calculating the hash value using HW */
+		hash_find(buf, bytes_to_read, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
 
-		SHA256_Final(digest, &sha256_ctx);
-
-		if (memcmp(digest, hash_table->hash, HASH_LEN))
+		if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
 		{
 			dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: Failed partition hash[%d] verification\n", name, block_num);
 			return -1;
@@ -299,7 +293,7 @@
 }
 
 /* Verify a given partitinon */
-static int verify_partition(char* name,
+static int verify_partition(char *name,
 						uint32_t size,
 						mdtp_fwlock_mode_t hash_mode,
 						uint32_t total_num_blocks,
@@ -382,10 +376,11 @@
 static void validate_DIP_and_firmware()
 {
 	int ret;
-	DIP_t* enc_dip;
-	DIP_t* dec_dip;
+	DIP_t *enc_dip;
+	DIP_t *dec_dip;
 	uint32_t verified = 0;
 	verify_result_t verify_result;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	enc_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
 	if (enc_dip == NULL)
@@ -461,22 +456,18 @@
 
 int mdtp_fwlock_verify_lock()
 {
-	int provisioned_fuse;
+	int ret;
+	bool enabled;
 
-	block_size = mmc_get_device_blocksize();
-
-	provisioned_fuse = mdtp_tzbsp_get_provisioned_fuse();
-	if(provisioned_fuse < 0)
+	ret = mdtp_fuse_get_enabled(&enabled);
+	if(ret)
 	{
-		dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get DIP_PROVISIONED fuse\n");
+		dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
 		return -1;
 	}
 
-	if (!provisioned_fuse)
-	{
-		provision_DIP();
-	}
-	else
+	/* Continue with Firmware Lock verification only if enabled by eFuse */
+	if (enabled)
 	{
 		validate_DIP_and_firmware();
 	}
@@ -486,22 +477,10 @@
 
 /********************************************************************************/
 
-/* Functions communicating with TZBSP */
-
-static int mdtp_tzbsp_get_provisioned_fuse()
-{
-	return 1;
-}
-
-static int mdtp_tzbsp_set_provisioned_fuse()
-{
-	return 0;
-}
-
 /* 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)
+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_p;
 	unsigned char hash[HASH_LEN];
 	SHA256_CTX sha256_ctx;
 	int ret;
@@ -538,9 +517,9 @@
 	return 0;
 }
 
-static int mdtp_tzbsp_enc_hash_DIP(DIP_t* dec_dip, DIP_t* enc_dip)
+static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
 {
-	unsigned char* hash_p;
+	unsigned char *hash_p;
 	SHA256_CTX sha256_ctx;
 	int ret;
 
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index 68914f4..9975899 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -107,6 +107,9 @@
 /* Start Firmware Lock verification process */
 int mdtp_fwlock_verify_lock();
 
+/* Return whether the MDTP is currently enabled or disabled in HW */
+int mdtp_fuse_get_enabled(bool *enabled);
+
 /* Display the "Firmware Valid" screen */
 void show_OK_msg();
 
diff --git a/app/aboot/mdtp_fuse.c b/app/aboot/mdtp_fuse.c
new file mode 100644
index 0000000..c4abd19
--- /dev/null
+++ b/app/aboot/mdtp_fuse.c
@@ -0,0 +1,257 @@
+/* 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 "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 <debug.h>
+#include <target.h>
+#include <mmc.h>
+#include <partition_parser.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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)
+
+/********************************************************************************/
+
+typedef union
+{
+    struct {
+		uint8_t enable1       : 1;
+		uint8_t disable1      : 1;
+		uint8_t enable2       : 1;
+		uint8_t disable2      : 1;
+		uint8_t enable3       : 1;
+		uint8_t disable3      : 1;
+		uint8_t reserved1     : 1;
+		uint8_t reserved2     : 1;
+	} bitwise;
+	uint8_t mask;
+} mdtp_eFuses_t;
+
+typedef struct metadata {
+	mdtp_eFuses_t eFuses;
+} metadata_t;
+
+/********************************************************************************/
+
+/**
+ * Checks if we are in test mode according to relevant eFuses
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+static int is_test_mode(void)
+{
+	static int test_mode_set = 0;
+	static int test_mode = 0;
+	int ret = 0;
+	uint32_t status_low = 0;
+	uint32_t status_high = 0;
+
+#define SECBOOT_FUSE       0x01
+#define SHK_FUSE           0x02
+#define DEBUG_FUSE         0x04
+
+    /* Make sure we only read the test mode once */
+	if (test_mode_set)
+		return test_mode;
+
+	ret = scm_svc_get_secure_state(&status_low, &status_high);
+
+	if(ret == 0)
+	{
+		/* (SECBOOT_FUSE | SHK_FUSE | DEBUG_FUSE) implies that none of the fuses are blown */
+		if((status_low & (SECBOOT_FUSE | SHK_FUSE | DEBUG_FUSE)) == (SECBOOT_FUSE | SHK_FUSE | DEBUG_FUSE))
+			test_mode = 1;
+	}
+	else
+	{
+		dprintf(CRITICAL, "mdtp: is_test_mode: qsee_get_secure_state returned error: %d, status.value[0]: %d", ret, status_low);
+		test_mode = 0;
+    }
+
+	test_mode_set = 1;
+	dprintf(INFO, "mdtp: is_test_mode: test mode is set to %d", test_mode);
+
+	return test_mode;
+}
+
+/**
+ * Read the Firmware Lock Metadata from EMMC
+ *
+ * @param metadata - Read a metadata block holding eFuse emulation from MDTP partition.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+static int read_metadata(metadata_t *metadata)
+{
+	unsigned long long ptn = 0;
+	uint32_t actual_size;
+	char metadata_block[MAX_METADATA_SIZE];
+	int index = INVALID_PTN;
+	uint32_t block_size = mmc_get_device_blocksize();
+
+	index = partition_get_index("mdtp");
+	ptn = partition_get_offset(index);
+
+	if(ptn == 0)
+	{
+		return -1;
+	}
+
+	if (sizeof(metadata_t) > MAX_METADATA_SIZE)
+	{
+		dprintf(CRITICAL, "mdtp: read_metadata: ERROR, meta data size %d too big\n", sizeof(metadata_t));
+		return -1;
+	}
+
+	actual_size = ROUNDUP(MAX_METADATA_SIZE, block_size);
+
+	if(mmc_read(ptn, (void *)metadata_block, actual_size))
+	{
+		dprintf(CRITICAL, "mdtp: read_metadata: ERROR, cannot read mdtp info\n");
+		return -1;
+	}
+
+	memcpy(metadata, metadata_block, sizeof(metadata_t));
+
+	dprintf(INFO, "mdtp: read_metadata: SUCCESS, read %d bytes\n", actual_size);
+
+	return 0;
+}
+
+/**
+ * read_QFPROM_fuse
+ *
+ * @param mask[out] - MDTP efuse value represented by a bitfield.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+static int read_QFPROM_fuse(uint8_t *mask)
+{
+	static const uint32_t row_address = MDTP_EFUSE_ADDRESS;
+	uint32_t addr_type = QFPROM_ADDR_SPACE_RAW;
+	uint32_t row_data[2] = {0};
+	uint32_t qfprom_api_status = 0;
+
+	/* Read the current row where the eFuse is located */
+	(void) qfprom_read_row_cmd(row_address, addr_type, row_data, &qfprom_api_status);
+	if (qfprom_api_status)
+	{
+			dprintf(CRITICAL, "mdtp: write_QFPROM_fuse: qsee_fuse_read failed. qfprom_api_status=%d", qfprom_api_status);
+			return -1;
+	}
+
+	/* Shift the read data to be reflected in mask */
+	*mask = (uint8_t)(row_data[0] >> MDTP_EFUSE_START);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * read_test_fuse
+ *
+ * @param mask[out] - MDTP efuse value represented by a bitfield.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+static int read_test_fuse(uint8_t *mask)
+{
+	int status = 0;
+	metadata_t metadata;
+
+	status = read_metadata(&metadata);
+	if (status) {
+		dprintf(CRITICAL, "mdtp: read_test_fuse: Failure getting metadata");
+		return -1;
+	}
+
+	*mask = metadata.eFuses.mask;
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * read_fuse
+ *
+ * @param mask[out] - MDTP efuse value represented by a bitfield.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+static int read_fuse(uint8_t *mask)
+{
+	if (is_test_mode())
+		return read_test_fuse(mask);
+	else
+		return read_QFPROM_fuse(mask);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * mdtp_fuse_get_enabled
+ *
+ * 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.
+ *
+ * @return - negative value for an error, 0 for success.
+ */
+int mdtp_fuse_get_enabled(bool *enabled)
+{
+	int status;
+	mdtp_eFuses_t eFuses;
+
+	status = read_fuse(&eFuses.mask);
+	if (status)
+	{
+		dprintf(CRITICAL, "mdtp: mdtp_fuse_get_enabled: Failure in reading fuse");
+		return -1;
+	}
+
+	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 78d4519..30d70d6 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -46,8 +46,6 @@
 extern void fbcon_putImage(struct fbimage *fbimg, bool flag);
 extern void mdelay(unsigned msecs);
 
-extern unsigned block_size;
-
 static struct fbimage mdtp_header;/* = {0};*/
 
 /********************************************************************************/
@@ -59,6 +57,7 @@
 	unsigned long long ptn = 0;
 	struct fbcon_config *fb_display = NULL;
 	struct fbimage *logo = &mdtp_header;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	index = partition_get_index("mdtp");
 	if (index == 0) {
@@ -96,6 +95,7 @@
 	unsigned long long ptn = 0;
 	struct fbcon_config *fb_display = NULL;
 	struct fbimage *logo = &mdtp_header;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	index = partition_get_index("mdtp");
 	if (index == 0) {
@@ -133,6 +133,7 @@
 	unsigned long long ptn = 0;
 	struct fbcon_config *fb_display = NULL;
 	struct fbimage *logo = &mdtp_header;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	index = partition_get_index("mdtp");
 	if (index == 0) {
@@ -170,6 +171,7 @@
 	unsigned long long ptn = 0;
 	struct fbcon_config *fb_display = NULL;
 	struct fbimage *logo = &mdtp_header;
+	uint32_t block_size = mmc_get_device_blocksize();
 
 	index = partition_get_index("mdtp");
 	if (index == 0) {
diff --git a/app/aboot/rules.mk b/app/aboot/rules.mk
index 5560e12..95a8865 100644
--- a/app/aboot/rules.mk
+++ b/app/aboot/rules.mk
@@ -12,6 +12,6 @@
 ifeq ($(ENABLE_MDTP_SUPPORT),1)
 OBJS += \
 	$(LOCAL_DIR)/mdtp.o \
-	$(LOCAL_DIR)/mdtp_ui.o
+	$(LOCAL_DIR)/mdtp_ui.o \
+	$(LOCAL_DIR)/mdtp_fuse.o
 endif
-
diff --git a/arch/arm/arch.c b/arch/arm/arch.c
index dc171b4..6b5cf72 100644
--- a/arch/arm/arch.c
+++ b/arch/arm/arch.c
@@ -25,6 +25,7 @@
 #include <arch/ops.h>
 #include <arch/arm.h>
 #include <arch/arm/mmu.h>
+#include <arch/defines.h>
 #include <platform.h>
 
 #if ARM_CPU_CORTEX_A8
@@ -59,6 +60,8 @@
 	val |= (3<<22)|(3<<20);
 	__asm__ volatile("mcr	p15, 0, %0, c1, c0, 2" :: "r" (val));
 
+	isb();
+
 	/* set enable bit in fpexc */
 	__asm__ volatile("mrc  p10, 7, %0, c8, c0, 0" : "=r" (val));
 	val |= (1<<30);
diff --git a/dev/gcdb/display/gcdb_autopll.c b/dev/gcdb/display/gcdb_autopll.c
index 4a5ca26..2794203 100755
--- a/dev/gcdb/display/gcdb_autopll.c
+++ b/dev/gcdb/display/gcdb_autopll.c
@@ -148,7 +148,7 @@
 {
 	uint32_t refclk = 19200000;
 	uint32_t vco_rate = pll_data.vco_clock;
-	uint32_t tmp;
+	uint32_t tmp, mod;
 
 	vco_rate /= 2;
 	pll_data.dec_start = vco_rate / refclk;
@@ -161,11 +161,22 @@
 	pll_data.frac_start = tmp;
 
 	vco_rate *= 2; /* restore */
-	tmp = vco_rate / (refclk / 1000);/* div 1000 first */
-	tmp *= 1024;
-	tmp /= 1000;
-	tmp /= 10;
-	pll_data.lock_comp = tmp - 1;
+	if (pll_data.en_vco_zero_phase) {
+		tmp = vco_rate / (refclk / 1000);/* div 1000 first */
+		tmp *= 1024;
+		tmp /= 1000;
+		tmp /= 10;
+		pll_data.lock_comp = tmp - 1;
+	} else {
+		tmp = vco_rate / refclk;
+		mod = vco_rate % refclk;
+		tmp *= 127;
+		mod *= 127;
+		mod /= refclk;
+		tmp += mod;
+		tmp /= 10;
+		pll_data.lock_comp = tmp;
+	}
 
 	dprintf(SPEW, "%s: dec_start=0x%x dec_frac=0x%x lock_comp=0x%x\n", __func__,
 		pll_data.dec_start, pll_data.frac_start, pll_data.lock_comp);
@@ -203,6 +214,24 @@
 	return NO_ERROR;
 }
 
+#ifndef DISPLAY_EN_20NM_PLL_90_PHASE
+static void config_20nm_pll_vco_range(void)
+{
+	pll_data.vco_min = 300000000;
+	pll_data.vco_max = 1500000000;
+	pll_data.en_vco_zero_phase = 1;
+	dprintf(SPEW, "%s: Configured VCO for zero phase\n", __func__);
+}
+#else
+static void config_20nm_pll_vco_range(void)
+{
+	pll_data.vco_min = 1000000000;
+	pll_data.vco_max = 2000000000;
+	pll_data.en_vco_zero_phase = 0;
+	dprintf(SPEW, "%s: Configured VCO for 90 phase\n", __func__);
+}
+#endif
+
 static uint32_t calculate_vco_20nm(uint8_t bpp, uint8_t lanes)
 {
 	uint32_t vco, dsi_clk;
@@ -235,12 +264,12 @@
 	hr_oclk2 = 4;
 
 	/* If bitclock is more than VCO min value */
-	if (pll_data.halfbit_clock >= HALF_VCO_MIN_CLOCK_20NM) {
+	if (pll_data.halfbit_clock >= ((pll_data.vco_min) >> 1)) {
 		/* Direct Mode */
 		vco  = pll_data.halfbit_clock << 1;
 		/* support vco clock to max value only */
-		if (vco > VCO_MAX_CLOCK_20NM)
-			vco = VCO_MAX_CLOCK_20NM;
+		if (vco > (pll_data.vco_max))
+			vco = (pll_data.vco_max);
 
 		pll_data.directpath = 0x0;
 		pll_data.byte_clock = vco / 2 / hr_oclk2;
@@ -249,8 +278,8 @@
 		hr_oclk3 = hr_oclk2 * m / n * bpp_m / bpp_n / lanes;
 	} else {
 		/* Indirect Mode */
-		mod =  VCO_MIN_CLOCK_20NM % (4 * pll_data.halfbit_clock );
-		ndiv = VCO_MIN_CLOCK_20NM / (4 * pll_data.halfbit_clock );
+		mod =  (pll_data.vco_min) % (4 * pll_data.halfbit_clock );
+		ndiv = (pll_data.vco_min) / (4 * pll_data.halfbit_clock );
 		if (mod)
 			ndiv += 1;
 
@@ -288,6 +317,9 @@
 	calculate_bitclock(pinfo);
 
 	if (pinfo->mipi.mdss_dsi_phy_db->is_pll_20nm)
+		config_20nm_pll_vco_range();
+
+	if (pinfo->mipi.mdss_dsi_phy_db->is_pll_20nm)
 		ret = calculate_vco_20nm(pinfo->bpp, pinfo->mipi.num_of_lanes);
 	else
 		ret = calculate_vco_28nm(pinfo->bpp, pinfo->mipi.num_of_lanes);
diff --git a/dev/gcdb/display/gcdb_autopll.h b/dev/gcdb/display/gcdb_autopll.h
index b261a34..aca4463 100755
--- a/dev/gcdb/display/gcdb_autopll.h
+++ b/dev/gcdb/display/gcdb_autopll.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* 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
@@ -43,11 +43,6 @@
 #define HALFBIT_CLOCK3 44000000  /* VCO min clock div by 8 */
 #define HALFBIT_CLOCK4 40000000  /* VCO min clock div by 9 */
 
-#define VCO_MIN_CLOCK_20NM 	300000000
-#define VCO_MAX_CLOCK_20NM 	1500000000
-
-#define HALF_VCO_MIN_CLOCK_20NM (VCO_MIN_CLOCK_20NM >> 1)
-
 #define HALFBIT_CLOCK1_20NM 	500000000 /* VCO min clock div by 2 */
 #define HALFBIT_CLOCK2_20NM 	250000000  /* VCO min clock div by 4 */
 #define HALFBIT_CLOCK3_20NM 	125000000  /* VCO min clock div by 8 */
diff --git a/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h b/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h
new file mode 100755
index 0000000..6f09f38
--- /dev/null
+++ b/dev/gcdb/display/include/panel_jdi_a216_fhd_video.h
@@ -0,0 +1,165 @@
+/* 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+
+#ifndef _PANEL_JDI_A216_FHD_VIDEO_H_
+#define _PANEL_JDI_A216_FHD_VIDEO_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config jdi_a216_fhd_video_panel_data = {
+	"qcom,mdss_dsi_jdi_a216_fhd_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution jdi_a216_fhd_video_panel_res = {
+	1080, 1920, 32, 20, 12, 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info jdi_a216_fhd_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char jdi_a216_fhd_video_on_cmd0[] = {
+	0x51, 0xFF, 0x15, 0x80
+};
+
+static char jdi_a216_fhd_video_on_cmd1[] = {
+	0x53, 0x0C, 0x15, 0x80
+};
+
+static char jdi_a216_fhd_video_on_cmd2[] = {
+	0x55, 0x00, 0x15, 0x80
+};
+
+static char jdi_a216_fhd_video_on_cmd3[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static char jdi_a216_fhd_video_on_cmd4[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd jdi_a216_fhd_video_on_command[] = {
+	{0x4, jdi_a216_fhd_video_on_cmd0, 0x0a},
+	{0x4, jdi_a216_fhd_video_on_cmd1, 0x0a},
+	{0x4, jdi_a216_fhd_video_on_cmd2, 0x0a},
+	{0x4, jdi_a216_fhd_video_on_cmd3, 0x28},
+	{0x4, jdi_a216_fhd_video_on_cmd4, 0xc8},
+};
+
+#define JDI_A216_FHD_VIDEO_ON_COMMAND 5
+
+
+static char jdi_a216_fhd_videooff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char jdi_a216_fhd_videooff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd jdi_a216_fhd_video_off_command[] = {
+	{0x4, jdi_a216_fhd_videooff_cmd0, 0x32},
+	{0x4, jdi_a216_fhd_videooff_cmd1, 0x78}
+};
+
+#define JDI_A216_FHD_VIDEO_OFF_COMMAND 2
+
+
+static struct command_state jdi_a216_fhd_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info jdi_a216_fhd_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info jdi_a216_fhd_video_video_panel = {
+	0, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration jdi_a216_fhd_video_lane_config = {
+	4, 0, 1, 1, 1, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t jdi_a216_fhd_video_timings[] = {
+	0xce, 0x2e, 0x1e, 0x00, 0x5a, 0x5c, 0x24, 0x30, 0x24, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing jdi_a216_fhd_video_timing_info = {
+	0x0, 0x04, 0x0a, 0x2c
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence jdi_a216_fhd_video_reset_seq = {
+	{1, 0, 1, }, {20, 200, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight jdi_a216_fhd_video_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#endif /*_PANEL_JDI_A216_FHD_VIDEO_H_*/
diff --git a/dev/gcdb/display/include/panel_r61318_hd_video.h b/dev/gcdb/display/include/panel_r61318_hd_video.h
index 44b318e..b1dc22c 100644
--- a/dev/gcdb/display/include/panel_r61318_hd_video.h
+++ b/dev/gcdb/display/include/panel_r61318_hd_video.h
@@ -272,11 +272,11 @@
 /* Panel timing                                                              */
 /*---------------------------------------------------------------------------*/
 static const uint32_t r61318_hd_video_timings[] = {
-	0xab, 0x40, 0x33, 0x00, 0x57, 0x51, 0x35, 0x42, 0x52, 0x03, 0x04, 0x00
+	0xab, 0x1c, 0x14, 0x00, 0x2a, 0x27, 0x18, 0x1e, 0x21, 0x03, 0x04, 0x00
 };
 
 static struct panel_timing r61318_hd_video_timing_info = {
-	0, 4, 0x1e, 0x33
+	0, 4, 0x20, 0x2e
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_r63417_1080p_video.h b/dev/gcdb/display/include/panel_r63417_1080p_video.h
new file mode 100644
index 0000000..dad028a
--- /dev/null
+++ b/dev/gcdb/display/include/panel_r63417_1080p_video.h
@@ -0,0 +1,313 @@
+/* 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+
+#ifndef _PANEL_R63417_1080P_VIDEO_H_
+#define _PANEL_R63417_1080P_VIDEO_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config r63417_1080p_video_panel_data = {
+	"qcom,mdss_dsi_r63417_1080p_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution r63417_1080p_video_panel_res = {
+	1080, 1920, 100, 12, 60, 0, 25, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info r63417_1080p_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char r63417_1080p_video_on_cmd0[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x11, 0x00, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd1[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xB0, 0x04, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd2[] = {
+	0x07, 0x00, 0x29, 0xC0,
+	0xB3, 0x14, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd3[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xB6, 0x3A, 0xC3, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd4[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xC0, 0x00, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd5[] = {
+	0x23, 0x00, 0x29, 0xC0,
+	0xC1, 0xC4, 0x60, 0x10,
+	0xEB, 0xFF, 0x6F, 0xCE,
+	0xFF, 0xFF, 0x17, 0x12,
+	0x58, 0x73, 0xAE, 0x31,
+	0x20, 0xC6, 0xFF, 0xFF,
+	0x1F, 0xF3, 0xFF, 0x5F,
+	0x10, 0x10, 0x10, 0x10,
+	0x00, 0x62, 0x01, 0x22,
+	0x22, 0x00, 0x01, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd6[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xC2, 0x31, 0xF7, 0x80,
+	0x08, 0x08, 0x00, 0x00,
+};
+
+static char r63417_1080p_video_on_cmd7[] = {
+	0x17, 0x00, 0x29, 0xC0,
+	0xC4, 0x70, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x06, 0x05,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x06, 0x05, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd8[] = {
+	0x29, 0x00, 0x29, 0xC0,
+	0xC6, 0xC8, 0x01, 0x69,
+	0x01, 0x69, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x0B, 0x17,
+	0x09, 0xC8, 0x08, 0x67,
+	0x08, 0x67, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x16, 0x18,
+	0x08, 0xFF, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd9[] = {
+	0x0A, 0x00, 0x29, 0xC0,
+	0xCB, 0x31, 0xFC, 0x3F,
+	0x8C, 0x00, 0x00, 0x00,
+	0x00, 0xC0, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd10[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xCC, 0x0B, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd11[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xD0, 0x22, 0x82, 0xBB,
+	0x19, 0x99, 0x4C, 0x19,
+	0x19, 0x0C, 0x00, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd12[] = {
+	0x1a, 0x00, 0x29, 0xC0,
+	0xD3, 0x1B, 0x33, 0xBB,
+	0xBB, 0xB3, 0x33, 0x33,
+	0x33, 0x01, 0x01, 0x00,
+	0xA0, 0xD8, 0xA0, 0x0D,
+	0x55, 0x55, 0x33, 0x3B,
+	0x37, 0x72, 0x07, 0x3D,
+	0xBF, 0x44, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd13[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xD5, 0x06, 0x00, 0x00,
+	0x01, 0x67, 0x01, 0x67,
+};
+
+static char r63417_1080p_video_on_cmd14[] = {
+	0x1f, 0x00, 0x29, 0xC0,
+	0xC7, 0x0C, 0x1B, 0x22,
+	0x2B, 0x37, 0x43, 0x4C,
+	0x5B, 0x3F, 0x47, 0x52,
+	0x5F, 0x67, 0x6B, 0x6E,
+	0x0C, 0x1B, 0x22, 0x2B,
+	0x37, 0x43, 0x4C, 0x5B,
+	0x3F, 0x47, 0x52, 0x5F,
+	0x67, 0x6B, 0x6E, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd15[] = {
+	0x14, 0x00, 0x29, 0xC0,
+	0xC8, 0x01, 0x00, 0x00,
+	0x03, 0xFB, 0xFB, 0xEF,
+	0x00, 0x00, 0x03, 0xFB,
+	0xFB, 0xEF, 0x00, 0x00,
+	0x03, 0xFB, 0xFB, 0xEF,
+};
+
+static char r63417_1080p_video_on_cmd16[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x51, 0xFF, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd17[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x53, 0x2C, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd18[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x55, 0x03, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd19[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x35, 0x00, 0xFF, 0xFF,
+};
+
+static char r63417_1080p_video_on_cmd20[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x29, 0x00, 0xFF, 0xFF,
+};
+
+static struct mipi_dsi_cmd r63417_1080p_video_on_command[] = {
+	{0x8, r63417_1080p_video_on_cmd0, 0x78},
+	{0x8, r63417_1080p_video_on_cmd1, 0x00},
+	{0xc, r63417_1080p_video_on_cmd2, 0x00},
+	{0x8, r63417_1080p_video_on_cmd3, 0x00},
+	{0x8, r63417_1080p_video_on_cmd4, 0x00},
+	{0x28, r63417_1080p_video_on_cmd5, 0x00},
+	{0xc, r63417_1080p_video_on_cmd6, 0x00},
+	{0x1c, r63417_1080p_video_on_cmd7, 0x00},
+	{0x30, r63417_1080p_video_on_cmd8, 0x00},
+	{0x10, r63417_1080p_video_on_cmd9, 0x00},
+	{0x8, r63417_1080p_video_on_cmd10, 0x00},
+	{0x10, r63417_1080p_video_on_cmd11, 0x00},
+	{0x20, r63417_1080p_video_on_cmd12, 0x00},
+	{0xc, r63417_1080p_video_on_cmd13, 0x00},
+	{0x24, r63417_1080p_video_on_cmd14, 0x00},
+	{0x18, r63417_1080p_video_on_cmd15, 0x00},
+	{0x8, r63417_1080p_video_on_cmd16, 0x00},
+	{0x8, r63417_1080p_video_on_cmd17, 0x00},
+	{0x8, r63417_1080p_video_on_cmd18, 0x00},
+	{0x8, r63417_1080p_video_on_cmd19, 0x00},
+	{0x8, r63417_1080p_video_on_cmd20, 0x64}
+};
+
+#define R63417_1080P_VIDEO_ON_COMMAND 21
+
+
+static char r63417_1080p_videooff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char r63417_1080p_videooff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r63417_1080p_video_off_command[] = {
+	{0x4, r63417_1080p_videooff_cmd0, 0x32},
+	{0x4, r63417_1080p_videooff_cmd1, 0x78}
+};
+
+#define R63417_1080P_VIDEO_OFF_COMMAND 2
+
+
+static struct command_state r63417_1080p_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info r63417_1080p_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info r63417_1080p_video_video_panel = {
+	1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration r63417_1080p_video_lane_config = {
+	4, 0, 1, 1, 1, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t r63417_1080p_video_timings[] = {
+	0xAE, 0x44, 0x37, 0x00, 0x5D, 0x55, 0x39, 0x46, 0x5B, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing r63417_1080p_video_timing_info = {
+	0, 4, 0x1e, 0x34
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence r63417_1080p_video_reset_seq = {
+	{1, 0, 1, }, {20, 2, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight r63417_1080p_video_backlight = {
+	1, 1, 255, 0, 2, "bl_ctrl_dcs"
+};
+
+#endif /*_PANEL_R63417_1080P_VIDEO_H_*/
diff --git a/include/dev/flash.h b/include/dev/flash.h
index 25257f1..9c41561 100644
--- a/include/dev/flash.h
+++ b/include/dev/flash.h
@@ -41,6 +41,7 @@
 
 struct flash_info {
 	unsigned id;
+	unsigned id2;
 	unsigned type;
 	unsigned vendor;
 	unsigned device;
diff --git a/platform/msm_shared/include/mipi_dsi.h b/platform/msm_shared/include/mipi_dsi.h
index 43c9ce6..c2ddd9b 100644
--- a/platform/msm_shared/include/mipi_dsi.h
+++ b/platform/msm_shared/include/mipi_dsi.h
@@ -162,6 +162,9 @@
 	uint32_t  halfbit_clock;
 	uint32_t  vco_clock;
 	uint32_t  vco_delay;
+	uint32_t  vco_min;
+	uint32_t  vco_max;
+	uint32_t  en_vco_zero_phase;
 	uint8_t   directpath;
 	uint8_t   posdiv1;
 	uint8_t   posdiv3;
diff --git a/platform/msm_shared/include/qmp_phy.h b/platform/msm_shared/include/qmp_phy.h
index c112919..ab669d7 100644
--- a/platform/msm_shared/include/qmp_phy.h
+++ b/platform/msm_shared/include/qmp_phy.h
@@ -30,6 +30,12 @@
 
 #include <platform/iomap.h>
 
+struct qmp_reg
+{
+	uint32_t off;
+	uint32_t val;
+};
+
 /* QMP register offsets */
 #define QSERDES_COM_DEC_START1               (PLATFORM_QMP_OFFSET + 0xA4)
 #define QSERDES_COM_DEC_START2               (PLATFORM_QMP_OFFSET + 0x104)
diff --git a/platform/msm_shared/include/qpic_nand.h b/platform/msm_shared/include/qpic_nand.h
index f640cf8..14282ec 100644
--- a/platform/msm_shared/include/qpic_nand.h
+++ b/platform/msm_shared/include/qpic_nand.h
@@ -52,6 +52,7 @@
 #define NAND_SFLASHC_EXEC_CMD                              NAND_REG(0x003C)
 #define NAND_READ_ID                                       NAND_REG(0x0040)
 #define NAND_READ_STATUS                                   NAND_REG(0x0044)
+#define NAND_READ_ID2                                      NAND_REG(0x0048)
 #define NAND_CONFIG_DATA                                   NAND_REG(0x0050)
 #define NAND_CONFIG                                        NAND_REG(0x0054)
 #define NAND_CONFIG_MODE                                   NAND_REG(0x0058)
@@ -310,7 +311,9 @@
 struct flash_id
 {
 	unsigned flash_id;
+	unsigned flash_id2;
 	unsigned mask;
+	unsigned mask2;
 	unsigned density;
 	unsigned widebus;
 	unsigned pagesize;
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index 6f92ee9..025a038 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -123,6 +123,23 @@
 } feature_version_rsp;
 
 typedef struct{
+	uint32 *status_ptr;
+	uint32 status_len;
+} get_secure_state_req;
+
+typedef struct{
+	uint32 status_low;
+	uint32 status_high;
+} get_secure_state_rsp;
+
+typedef struct{
+	uint32 row_address;
+	uint32 addr_type;
+	uint32 *row_data;
+	uint32 *qfprom_api_status;
+} qfprom_read_row_req;
+
+typedef struct{
   uint32 *keystore_ptr;
   uint32  keystore_len;
 } ssd_protect_keystore_req;
@@ -235,6 +252,7 @@
 #define IOMMU_SECURE_CFG            0x02
 
 #define TZ_INFO_GET_FEATURE_ID      0x03
+#define TZ_INFO_GET_SECURE_STATE    0x04
 
 #define PRNG_CMD_ID                 0x01
 #define IS_CALL_AVAIL_CMD           0x01
@@ -280,11 +298,30 @@
 int decrypt_scm_v2(uint32_t ** img_ptr, uint32_t * img_len_ptr);
 int encrypt_scm(uint32_t ** img_ptr, uint32_t * img_len_ptr);
 int scm_svc_version(uint32 * major, uint32 * minor);
+
+/**
+ * Check security status on the device. Returns the security check result.
+ * Bit value 0 means the check passing, and bit value 1 means the check failing.
+ *
+ * @state_low[out] : lower 32 bits of the state:
+ *                   Bit 0: secboot enabling check failed
+ *                   Bit 1: Sec HW key is not programmed
+ *                   Bit 2: debug disable check failed
+ *                   Bit 3: Anti-rollback check failed
+ *                   Bit 4: fuse config check failed
+ *                   Bit 5: rpmb fuse check failed
+ * @state_high[out] : highr 32 bits of the state.
+ *
+ * Returns 0 on success, negative on failure.
+ */
+int scm_svc_get_secure_state(uint32_t *state_low, uint32_t *state_high);
+
 int scm_protect_keystore(uint32_t * img_ptr, uint32_t  img_len);
 
 #define SCM_SVC_FUSE                0x08
 #define SCM_BLOW_SW_FUSE_ID         0x01
 #define SCM_IS_SW_FUSE_BLOWN_ID     0x02
+#define SCM_QFPROM_READ_ROW_ID      0x05
 
 #define HLOS_IMG_TAMPER_FUSE        0
 
@@ -332,6 +369,19 @@
 
 void set_tamper_fuse_cmd();
 
+/**
+ * Reads the row data of the specified QFPROM row address.
+ *
+ * @row_address[in] : Row address in the QFPROM region to read.
+ * @addr_type[in] : Raw or corrected address.
+ * @row_data[in] : Pointer to the data to be read.
+ * @qfprom_api_status[out] : Status of the read operation.
+ *
+ * Returns Any errors while reading data from the specified
+ * Returns 0 on success, negative on failure.
+ */
+int qfprom_read_row_cmd(uint32_t row_address, uint32_t addr_type, uint32_t *row_data, uint32_t *qfprom_api_status);
+
 int scm_halt_pmic_arbiter();
 int scm_call_atomic2(uint32_t svc, uint32_t cmd, uint32_t arg1, uint32_t arg2);
 int restore_secure_cfg(uint32_t id);
diff --git a/platform/msm_shared/include/sdhci_msm.h b/platform/msm_shared/include/sdhci_msm.h
index 0cdfe2f..d3bc7f5 100644
--- a/platform/msm_shared/include/sdhci_msm.h
+++ b/platform/msm_shared/include/sdhci_msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* 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
@@ -76,7 +76,9 @@
 #define SDCC_DLL_EN                               BIT(16)
 #define SDCC_DLL_CDR_EN                           BIT(17)
 #define SDCC_DLL_CLK_OUT_EN                       BIT(18)
+#define SDCC_FLL_CYCLE_CNT                        BIT(18)
 #define SDCC_DLL_CDR_EXT_EN                       BIT(19)
+#define SDCC_DLL_CLOCK_DISABLE                    BIT(21)
 #define SDCC_DLL_PDN_EN                           BIT(29)
 #define SDCC_DLL_RESET_EN                         BIT(30)
 #define SDCC_DLL_CONFIG_MCLK_START                0x18
@@ -124,6 +126,8 @@
 
 #define SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0     0x11C
 
+#define TCXO_FREQ                                 19200000
+
 struct sdhci_msm_data
 {
 	uint32_t pwrctl_base;
diff --git a/platform/msm_shared/mipi_dsi_autopll_20nm.c b/platform/msm_shared/mipi_dsi_autopll_20nm.c
index 4926541..da0551e 100644
--- a/platform/msm_shared/mipi_dsi_autopll_20nm.c
+++ b/platform/msm_shared/mipi_dsi_autopll_20nm.c
@@ -231,8 +231,10 @@
 	writel(((pd->lock_comp >> 16) & 0xff),
 				pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP3);
 
-	writel(0x01, pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN);
-
+	if (pd->en_vco_zero_phase)
+		writel(0x01, pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN);
+	else
+		writel(0x0d, pll_base + MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN);
 
 	dprintf(SPEW, "div frac1=0x%x, div frac2 = 0x%x, div frac3=0x%x\n",
 			readl(pll_base + MMSS_DSI_PHY_PLL_DIV_FRAC_START1),
diff --git a/platform/msm_shared/qmp_usb30_phy.c b/platform/msm_shared/qmp_usb30_phy.c
index dbd5f1d..821c0b2 100644
--- a/platform/msm_shared/qmp_usb30_phy.c
+++ b/platform/msm_shared/qmp_usb30_phy.c
@@ -45,12 +45,85 @@
 #define QMP_PHY_MAX_TIMEOUT            1000
 #define PHYSTATUS                      BIT(6)
 
+struct qmp_reg qmp_settings[] =
+{
+	{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 */
+	{0xd0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */
+	{0xdc, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
+	{0xe0, 0x55}, /* QSERDES_COM_DIV_FRAC_START2_MODE0 */
+	{0xe4, 0x03}, /* QSERDES_COM_DIV_FRAC_START3_MODE0 */
+	{0x78, 0x0b}, /* QSERDES_COM_CP_CTRL_MODE0 */
+	{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 */
+	{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 */
+	{0x128, 0x00}, /* QSERDES_COM_VCO_TUNE_MAP */
+	{0xc, 0x0a}, /* QSERDES_COM_BG_TIMER */
+	{0x10, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */
+	{0x1c, 0x31}, /* QSERDES_COM_SSC_PER1 */
+	{0x20, 0x01}, /* QSERDES_COM_SSC_PER2 */
+	{0x14, 0x00}, /* QSERDES_COM_SSC_ADJ_PER1 */
+	{0x18, 0x00}, /* QSERDES_COM_SSC_ADJ_PER2 */
+	{0x24, 0xde}, /* QSERDES_COM_SSC_STEP_SIZE1 */
+	{0x28, 0x07}, /* QSERDES_COM_SSC_STEP_SIZE2 */
+	{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 */
+	{0x508, 0x77}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */
+	{0x50c, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */
+	{0x514, 0x04}, /* QSERDES_RX_SIGDET_CNTRL */
+	{0x518, 0x1b}, /* QSERDES_RX_SIGDET_LVL */
+	{0x51c, 0x16}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */
+	{0x268, 0x45}, /* QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN */
+	{0x2ac, 0x12}, /* QSERDES_TX_RCV_DETECT_LVL_2 */
+	{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 */
+	{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 */
+};
+
 __WEAK uint32_t target_override_pll()
 {
 	return 0;
 }
 
-static void qmp_phy_qmp_reset()
+__WEAK uint32_t platform_get_qmp_rev()
+{
+	return 0x10000000;
+}
+
+/* USB3.0 QMP phy reset */
+static void qmp_phy_qmp_reset(void)
 {
 	int ret = 0;
 	uint32_t val;
@@ -154,68 +227,88 @@
 void usb30_qmp_phy_init()
 {
 	int timeout = QMP_PHY_MAX_TIMEOUT;
+	uint32_t rev_id = 0;
+	uint32_t phy_status = 0;
+	uint32_t qmp_reg_size;
+	uint32_t i;
+
+	rev_id = platform_get_qmp_rev();
 
 	/* Sequence as per HPG */
-
 	writel(0x01, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_DOWN_CONTROL);
-	writel(0x08, QMP_PHY_BASE + QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
 
-	if (target_override_pll())
-		writel(0xE1, QMP_PHY_BASE + QSERDES_COM_PLL_VCOTAIL_EN);
-
-	writel(0x82, QMP_PHY_BASE + QSERDES_COM_DEC_START1);
-	writel(0x03, QMP_PHY_BASE + QSERDES_COM_DEC_START2);
-	writel(0xD5, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START1);
-	writel(0xAA, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START2);
-	writel(0x4D, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START3);
-	writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP_EN);
-	writel(0x2B, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP1);
-	writel(0x68, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP2);
-	writel(0x7C, QMP_PHY_BASE + QSERDES_COM_PLL_CRCTRL);
-	writel(0x02, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETI);
-	writel(0x1F, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETP);
-	writel(0x0F, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETP);
-	writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETI);
-	writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IE_TRIM);
-	writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IP_TRIM);
-	writel(0x46, QMP_PHY_BASE + QSERDES_COM_PLL_CNTRL);
-
-	/* CDR Settings */
-	writel(0xDA, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL1);
-	writel(0x42, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL2);
-
-	/* Calibration Settings */
-	writel(0x90, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL);
-	if (target_override_pll())
-		writel(0x07, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
+	if (rev_id >= 0x20000000)
+	{
+		qmp_reg_size = sizeof(qmp_settings) / sizeof(struct qmp_reg);
+		for (i = 0 ; i < qmp_reg_size; i++)
+			writel(qmp_settings[i].val, QMP_PHY_BASE + qmp_settings[i].off);
+	}
 	else
-		writel(0x05, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
+	{
+		writel(0x08, QMP_PHY_BASE + QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
 
-	writel(0x20, QMP_PHY_BASE + QSERDES_COM_RES_CODE_START_SEG1);
-	writel(0x77, QMP_PHY_BASE + QSERDES_COM_RES_CODE_CAL_CSR);
-	writel(0x15, QMP_PHY_BASE + QSERDES_COM_RES_TRIM_CONTROL);
-	writel(0x03, QMP_PHY_BASE + QSERDES_TX_RCV_DETECT_LVL);
-	writel(0x02, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2);
-	writel(0x6C, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3);
-	writel(0xC7, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4);
-	writel(0x40, QMP_PHY_BASE + QSERDES_RX_SIGDET_ENABLES);
-	writel(0x73, QMP_PHY_BASE + QSERDES_RX_SIGDET_CNTRL);
-	writel(0x06, QMP_PHY_BASE + QSERDES_RX_SIGDET_DEGLITCH_CNTRL);
-	writel(0x48, QMP_PHY_BASE + PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL);
-	writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_EN_CENTER);
-	writel(0x02, QMP_PHY_BASE + QSERDES_COM_SSC_ADJ_PER1);
-	writel(0x31, QMP_PHY_BASE + QSERDES_COM_SSC_PER1);
-	writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_PER2);
-	writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE1);
-	writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE2);
-	writel(0x08, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_STATE_CONFIG2);
+		if (target_override_pll())
+			writel(0xE1, QMP_PHY_BASE + QSERDES_COM_PLL_VCOTAIL_EN);
 
-	writel(0x00, QMP_PHY_BASE + PCIE_USB3_PHY_SW_RESET);
-	writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START);
+		writel(0x82, QMP_PHY_BASE + QSERDES_COM_DEC_START1);
+		writel(0x03, QMP_PHY_BASE + QSERDES_COM_DEC_START2);
+		writel(0xD5, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START1);
+		writel(0xAA, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START2);
+		writel(0x4D, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START3);
+		writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP_EN);
+		writel(0x2B, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP1);
+		writel(0x68, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP2);
+		writel(0x7C, QMP_PHY_BASE + QSERDES_COM_PLL_CRCTRL);
+		writel(0x02, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETI);
+		writel(0x1F, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETP);
+		writel(0x0F, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETP);
+		writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETI);
+		writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IE_TRIM);
+		writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IP_TRIM);
+		writel(0x46, QMP_PHY_BASE + QSERDES_COM_PLL_CNTRL);
+
+		/* CDR Settings */
+		writel(0xDA, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL1);
+		writel(0x42, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL2);
+
+		/* Calibration Settings */
+		writel(0x90, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL);
+		if (target_override_pll())
+			writel(0x07, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
+		else
+			writel(0x05, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
+
+		writel(0x20, QMP_PHY_BASE + QSERDES_COM_RES_CODE_START_SEG1);
+		writel(0x77, QMP_PHY_BASE + QSERDES_COM_RES_CODE_CAL_CSR);
+		writel(0x15, QMP_PHY_BASE + QSERDES_COM_RES_TRIM_CONTROL);
+		writel(0x03, QMP_PHY_BASE + QSERDES_TX_RCV_DETECT_LVL);
+		writel(0x02, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2);
+		writel(0x6C, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3);
+		writel(0xC7, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4);
+		writel(0x40, QMP_PHY_BASE + QSERDES_RX_SIGDET_ENABLES);
+		writel(0x73, QMP_PHY_BASE + QSERDES_RX_SIGDET_CNTRL);
+		writel(0x06, QMP_PHY_BASE + QSERDES_RX_SIGDET_DEGLITCH_CNTRL);
+		writel(0x48, QMP_PHY_BASE + PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL);
+		writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_EN_CENTER);
+		writel(0x02, QMP_PHY_BASE + QSERDES_COM_SSC_ADJ_PER1);
+		writel(0x31, QMP_PHY_BASE + QSERDES_COM_SSC_PER1);
+		writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_PER2);
+		writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE1);
+		writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE2);
+		writel(0x08, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_STATE_CONFIG2);
+
+		writel(0x00, QMP_PHY_BASE + PCIE_USB3_PHY_SW_RESET);
+		writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START);
+	}
 
 	clock_bumpup_pipe3_clk();
 
-	while ((readl(QMP_PHY_BASE + PCIE_USB3_PHY_PCS_STATUS) & PHYSTATUS))
+	if (rev_id >= 0x20000000)
+		phy_status = 0x77c;
+	else
+		phy_status = 0x728;
+
+	while ((readl(QMP_PHY_BASE + phy_status) & PHYSTATUS))
 	{
 		udelay(1);
 		timeout--;
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index 2608ee6..ae1cba0 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -33,6 +33,7 @@
 #include <debug.h>
 #include <string.h>
 #include <malloc.h>
+#include <bits.h>
 #include <sys/types.h>
 #include <platform.h>
 #include <platform/clock.h>
@@ -63,13 +64,14 @@
 static uint8_t* rdwr_buf;
 
 static struct flash_id supported_flash[] = {
-	/* Flash ID    ID Mask      Density(MB)    Wid Pgsz    Blksz              oobsz   8-bit ECCf */
-	{0x1590AC2C,   0xFFFFFFFF,  0x20000000,    0,  2048,   0x00020000,        0x40,   0},
-	{0x1590AA2C,   0xFFFFFFFF,  0x10000000,    0,  2048,   0x00020000,        0xE0,   1},
-	{0x2690AC2C,   0xFFFFFFFF,  0x20000000,    0,  4096,   0x00040000,        0xE0,   1},
-	{0x1590ACAD,   0xFFFFFFFF,  0x20000000,    0,  2048,   0x00020000,        0x80,   0},
-	{0x9590DC2C,   0xFFFFFFFF,  0x10000000,    0,  2048,   0x00020000,        0x40,   0},
-	{0x1590aa98,   0xFFFFFFFF,  0x10000000,    0,  2048,   0x00020000,        0x80,   1},
+	/* Flash ID  Flash ID2 ID Mask     ID Mask2  Density(MB)    Wid Pgsz    Blksz              oobsz   8-bit ECCf */
+	{0x1590AC2C, 0x56,     0xFFFFFFFF, 0xFF,     0x20000000,    0,  2048,   0x00020000,        0x40,   0},
+	{0x1590AC2C, 0x57,     0xFFFFFFFF, 0xFF,     0x20000000,    0,  2048,   0x00020000,        0x40,   1},
+	{0x1590AA2C, 0x06,     0xFFFFFFFF, 0x0,      0x10000000,    0,  2048,   0x00020000,        0xE0,   1},
+	{0x2690AC2C, 0x54,     0xFFFFFFFF, 0x0,      0x20000000,    0,  4096,   0x00040000,        0xE0,   1},
+	{0x1590ACAD, 0,        0xFFFFFFFF, 0x0,      0x20000000,    0,  2048,   0x00020000,        0x80,   0},
+	{0x9590DC2C, 0x56,     0xFFFFFFFF, 0x0,      0x10000000,    0,  2048,   0x00020000,        0x40,   0},
+	{0x1590aa98, 0x76,     0xFFFFFFFF, 0x0,      0x10000000,    0,  2048,   0x00020000,        0x80,   1},
 	/* Note: Width flag is 0 for 8 bit Flash and 1 for 16 bit flash   */
 };
 
@@ -201,8 +203,8 @@
 	struct cmd_element *cmd_list_ptr_start = ce_array;
 	int num_desc = 0;
 	uint32_t status;
-	uint32_t id;
-	uint32_t flash_cmd = NAND_CMD_FETCH_ID;
+	uint32_t id, id2;
+	uint32_t flash_cmd = NAND_CMD_FETCH_ID | BIT(19); //bit 19 needs to be set to get extended NAND ID
 	uint32_t exec_cmd = 1;
 	int nand_ret = NANDC_RESULT_SUCCESS;
 
@@ -241,9 +243,11 @@
 	}
 
 	/* Read the id */
-	id = qpic_nand_read_reg(NAND_READ_ID, BAM_DESC_UNLOCK_FLAG);
+	id = qpic_nand_read_reg(NAND_READ_ID, 0);
+	id2 = qpic_nand_read_reg(NAND_READ_ID2, BAM_DESC_UNLOCK_FLAG);
 
 	flash->id = id;
+	flash->id2 = id2;
 	flash->vendor = id & 0xff;
 	flash->device = (id >> 8) & 0xff;
 	flash->dev_cfg = (id >> 24) & 0xFF;
@@ -1221,8 +1225,10 @@
 	/* Check if we support the device */
 	for (index = 0; index < (ARRAY_SIZE(supported_flash)); index++)
 	{
-		if ((flash->id & supported_flash[index].mask) ==
-		    (supported_flash[index].flash_id & (supported_flash[index].mask)))
+		if (((flash->id & supported_flash[index].mask) ==
+		    (supported_flash[index].flash_id & (supported_flash[index].mask))) &&
+		    ((flash->id2 & supported_flash[index].mask2) ==
+		    (supported_flash[index].flash_id2 & (supported_flash[index].mask2))))
 		{
 			dev_found = 1;
 			break;
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 6042fab..b45fd3d 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -584,6 +584,48 @@
 	return ret;
 }
 
+int scm_svc_get_secure_state(uint32_t *state_low, uint32_t *state_high)
+{
+	get_secure_state_req req;
+	get_secure_state_rsp rsp;
+
+	int ret = 0;
+
+	scmcall_arg scm_arg = {0};
+	scmcall_ret scm_ret = {0};
+
+	if (!scm_arm_support)
+	{
+		req.status_ptr = (uint32_t*)&rsp;
+		req.status_len = sizeof(rsp);
+
+		ret = scm_call(TZBSP_SVC_INFO,
+					   TZ_INFO_GET_SECURE_STATE,
+					   &req,
+					   sizeof(req),
+					   NULL,
+					   0);
+	}
+	else
+	{
+		scm_arg.x0 = MAKE_SIP_SCM_CMD(TZBSP_SVC_INFO, TZ_INFO_GET_SECURE_STATE);
+		scm_arg.x1 = MAKE_SCM_ARGS(0x0);
+
+		ret = scm_call2(&scm_arg, &scm_ret);
+
+		rsp.status_low = scm_ret.x1;
+		rsp.status_high = scm_ret.x2;
+	}
+
+	if(!ret)
+	{
+		*state_low = rsp.status_low;
+		*state_high = rsp.status_high;
+	}
+
+	return ret;
+}
+
 int scm_protect_keystore(uint32_t * img_ptr, uint32_t  img_len)
 {
 	int                      ret=0;
@@ -818,6 +860,61 @@
 	return 0;
 }
 
+int qfprom_read_row_cmd(uint32_t row_address,
+                        uint32_t addr_type,
+                        uint32_t *row_data,
+                        uint32_t *qfprom_api_status)
+{
+	uint32_t svc_id;
+	uint32_t cmd_id;
+	void *cmd_buf;
+	void *rsp_buf;
+	size_t cmd_len;
+	size_t rsp_len;
+	qfprom_read_row_req req;
+	scmcall_arg scm_arg = {0};
+	scmcall_ret scm_ret = {0};
+
+	req.row_address = row_address;
+	req.addr_type = addr_type;
+	req.row_data = row_data;
+	req.qfprom_api_status = qfprom_api_status;
+
+	if (!scm_arm_support)
+	{
+		svc_id = SCM_SVC_FUSE;
+		cmd_id = SCM_QFPROM_READ_ROW_ID;
+		cmd_buf = (void *)&req;
+		cmd_len = sizeof(req);
+		rsp_buf = NULL;
+		rsp_len = 0;
+
+		if (scm_call(svc_id, cmd_id, cmd_buf, cmd_len, rsp_buf, rsp_len))
+		{
+			dprintf(CRITICAL, "Failed to call SCM_SVC_FUSE.SCM_QFPROM_READ_ROW_ID SCM\n");
+			return -1;
+		}
+	}
+	else
+	{
+		scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_FUSE, SCM_QFPROM_READ_ROW_ID);
+		scm_arg.x1 = MAKE_SCM_ARGS(0x4, SMC_PARAM_TYPE_VALUE, SMC_PARAM_TYPE_VALUE,
+										SMC_PARAM_TYPE_BUFFER_READWRITE, SMC_PARAM_TYPE_BUFFER_READWRITE);
+		scm_arg.x2 = req.row_address;
+		scm_arg.x3 = req.addr_type;
+		scm_arg.x4 = (uint32_t)req.row_data;
+		scm_arg.x5[0] = (uint32_t)req.qfprom_api_status;
+
+		if (scm_call2(&scm_arg, &scm_ret))
+		{
+			dprintf(CRITICAL, "Failed to call SCM_SVC_FUSE.SCM_QFPROM_READ_ROW_ID SCM\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * Switches the CE1 channel between ADM and register usage.
  * channel : AP_CE_REGISTER_USE, CE1 uses register interface
diff --git a/platform/msm_shared/sdhci_msm.c b/platform/msm_shared/sdhci_msm.c
index ba63845..4e83a55 100644
--- a/platform/msm_shared/sdhci_msm.c
+++ b/platform/msm_shared/sdhci_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* 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
@@ -294,14 +294,36 @@
 	REG_RMW32(host, SDCC_DLL_CONFIG_REG, SDCC_DLL_CONFIG_MCLK_START, SDCC_DLL_CONFIG_MCLK_WIDTH, reg_val);
 }
 
+static void sdhci_dll_clk_enable(struct sdhci_host *host, int enable)
+{
+	if (enable)
+	{
+		REG_WRITE32(host, (REG_READ32(host, SDCC_HC_REG_DLL_CONFIG_2) & ~SDCC_DLL_CLOCK_DISABLE), SDCC_HC_REG_DLL_CONFIG_2);
+	}
+	else
+	{
+		REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG);
+		REG_WRITE32(host, (REG_READ32(host, SDCC_HC_REG_DLL_CONFIG_2) | SDCC_DLL_CLOCK_DISABLE), SDCC_HC_REG_DLL_CONFIG_2);
+	}
+}
+
 /* Initialize DLL (Programmable Delay Line) */
 static uint32_t sdhci_msm_init_dll(struct sdhci_host *host)
 {
 	uint32_t pwr_save = 0;
 	uint32_t timeout = SDHCI_DLL_TIMEOUT;
+	uint32_t dll_cfg2;
+	uint32_t mclk_clk_freq = 0;
 
 	pwr_save = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & SDCC_DLL_PWR_SAVE_EN;
 
+	/* Dll sequence needs additional steps for sdcc core version 42 */
+	if (host->major == 1 && host->minor >= 0x42)
+	{
+		/* Disable DLL clock before configuring */
+		sdhci_dll_clk_enable(host, 0);
+	}
+
 	/* PWR SAVE to 0 */
 	if (pwr_save)
 		REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & ~SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC);
@@ -313,10 +335,33 @@
 	/* Set frequency field in DLL_CONFIG */
 	msm_set_dll_freq(host);
 
+	/* Configure the mclk freq based on the current clock rate
+	 * and fll cycle count as per hpg section 15.2.2
+	 */
+	if (host->major == 1 && host->minor >= 0x42)
+	{
+		dll_cfg2 = REG_READ32(host, SDCC_HC_REG_DLL_CONFIG_2);
+		if (dll_cfg2 & SDCC_FLL_CYCLE_CNT)
+			mclk_clk_freq = (host->cur_clk_rate / TCXO_FREQ) * 8;
+		else
+			mclk_clk_freq = (host->cur_clk_rate / TCXO_FREQ) * 4;
+
+		REG_WRITE32(host, ((REG_READ32(host, SDCC_HC_REG_DLL_CONFIG_2) & ~(0xFF << 10)) | (mclk_clk_freq << 10)), SDCC_HC_REG_DLL_CONFIG_2);
+
+		udelay(5);
+	}
+
 	/* Write 0 to DLL_RST */
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG);
 	/* Write 0 to DLL_PDN */
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG);
+
+	/* Set the mclk clock and enable the dll clock */
+	if (host->major == 1 && host->minor >= 0x42)
+	{
+		msm_set_dll_freq(host);
+		sdhci_dll_clk_enable(host, 1);
+	}
 	/* Write 1 to DLL_EN */
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_EN), SDCC_DLL_CONFIG_REG);
 	/* Write 1 to CLK_OUT_EN */
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
index 49ecf1b..e77f2d1 100644
--- a/platform/msm_shared/ucs.c
+++ b/platform/msm_shared/ucs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+/* 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
@@ -316,7 +316,9 @@
 	struct unmap_blk_desc *blk_desc;
 
 	param_list                    = (struct unmap_param_list *)param;
-	param_list->data_len          = (sizeof(struct unmap_param_list) - 1) << 0x8; /* n-1 */
+
+	// data length = size of unmap block descriptor struct (n-1) - size of data length field.
+	param_list->data_len          = ((sizeof(struct unmap_param_list) - 1) - 1) << 0x8;
 
 	param_list->blk_desc_data_len = sizeof(struct unmap_blk_desc) << 0x8;
 
diff --git a/platform/thulium/acpuclock.c b/platform/thulium/acpuclock.c
index 445146c..03e1490 100644
--- a/platform/thulium/acpuclock.c
+++ b/platform/thulium/acpuclock.c
@@ -70,12 +70,16 @@
 	}
 	else if(freq == MMC_CLK_96MHZ)
 	{
-		ret = clk_get_set_enable(clk_name, 100000000, true);
+		ret = clk_get_set_enable(clk_name, 96000000, true);
 	}
 	else if(freq == MMC_CLK_192MHZ)
 	{
 		ret = clk_get_set_enable(clk_name, 192000000, true);
 	}
+	else if(freq == MMC_CLK_400MHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 384000000, 1);
+	}
 	else
 	{
 		dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
diff --git a/platform/thulium/include/platform/iomap.h b/platform/thulium/include/platform/iomap.h
index 16b3e15..7f0cec5 100644
--- a/platform/thulium/include/platform/iomap.h
+++ b/platform/thulium/include/platform/iomap.h
@@ -38,6 +38,7 @@
 
 #define MSM_SHARED_IMEM_BASE        0x066BF000
 #define RESTART_REASON_ADDR         (MSM_SHARED_IMEM_BASE + 0x65C)
+#define BS_INFO_ADDR                (MSM_SHARED_IMEM_BASE + 0x6B0)
 
 #define MSM_GIC_DIST_BASE           (MSM_IOMAP_HMSS_START + 0x003C0000)
 #define MSM_GIC_REDIST_BASE         (MSM_IOMAP_HMSS_START + 0x00400000)
@@ -93,8 +94,8 @@
 #define APCS_CLOCK_BRANCH_ENA_VOTE  (CLK_CTL_BASE + 0x52004)
 
 /* UART Clocks */
-#define BLSP1_AHB_CBCR              (CLK_CTL_BASE + 0x29004)
-#define BLSP2_UART2_APPS_CBCR       (CLK_CTL_BASE + 0x29008)
+#define BLSP2_AHB_CBCR              (CLK_CTL_BASE + 0x25004)
+#define BLSP2_UART2_APPS_CBCR       (CLK_CTL_BASE + 0x29004)
 #define BLSP2_UART2_APPS_CMD_RCGR   (CLK_CTL_BASE + 0x2900C)
 #define BLSP2_UART2_APPS_CFG_RCGR   (CLK_CTL_BASE + 0x29010)
 #define BLSP2_UART2_APPS_M          (CLK_CTL_BASE + 0x29014)
@@ -163,7 +164,7 @@
 #define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL    0x4A3000
 
 /* DRV strength for sdcc */
-#define SDC1_HDRV_PULL_CTL           (TLMM_BASE_ADDR + 0x0003C000)
+#define SDC1_HDRV_PULL_CTL           (TLMM_BASE_ADDR + 0x0012C000)
 
 /* SDHCI - power control registers */
 #define SDCC_MCI_HC_MODE            (0x00000078)
@@ -177,7 +178,13 @@
 #define BOOT_CONFIG_OFFSET          0x00006044
 #define BOOT_CONFIG_REG             (SEC_CTRL_CORE_BASE + BOOT_CONFIG_OFFSET)
 
-/* Fix This */
-#define PLATFORM_QMP_OFFSET                  0x8
+/* QMP rev registers */
+#define USB3_PHY_REVISION_ID0       (QMP_PHY_BASE + 0x788)
+#define USB3_PHY_REVISION_ID1       (QMP_PHY_BASE + 0x78C)
+#define USB3_PHY_REVISION_ID2       (QMP_PHY_BASE + 0x790)
+#define USB3_PHY_REVISION_ID3       (QMP_PHY_BASE + 0x794)
+
+/* Dummy macro needed for compilation only */
+#define PLATFORM_QMP_OFFSET         0x0
 
 #endif
diff --git a/platform/thulium/platform.c b/platform/thulium/platform.c
index 315d05e..be0678c 100644
--- a/platform/thulium/platform.c
+++ b/platform/thulium/platform.c
@@ -44,9 +44,6 @@
 #define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
                            MMU_MEMORY_AP_READ_WRITE)
 
-/* RPM MSG RAM memory - cacheable, write through */
-#define MSG_RAM_MEMORY    (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
-                           MMU_MEMORY_AP_READ_WRITE)
 /* Peripherals - non-shared device */
 #define IOMAP_MEMORY      (MMU_MEMORY_TYPE_DEVICE_SHARED | \
                            MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
@@ -62,7 +59,6 @@
 	{    KERNEL_ADDR,       KERNEL_ADDR,       KERNEL_SIZE,      SCRATCH_MEMORY},
 	{    SCRATCH_ADDR,      SCRATCH_ADDR,      SCRATCH_SIZE,     SCRATCH_MEMORY},
 	{    MSM_SHARED_BASE,   MSM_SHARED_BASE,   MSM_SHARED_SIZE,  SCRATCH_MEMORY},
-	{    RPM_SS_MSG_RAM_START_ADDRESS_BASE, RPM_SS_MSG_RAM_START_ADDRESS_BASE, RPM_SS_MSG_RAM_START_ADDRESS_BASE_SIZE, MSG_RAM_MEMORY},
 };
 
 void platform_early_init(void)
@@ -134,3 +130,14 @@
 {
 	return readl(MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL);
 }
+
+addr_t get_bs_info_addr()
+{
+	return BS_INFO_ADDR;
+}
+
+uint32_t platform_get_qmp_rev()
+{
+	return readl(USB3_PHY_REVISION_ID3) << 24 | readl(USB3_PHY_REVISION_ID2) << 16 |
+		   readl(USB3_PHY_REVISION_ID1) << 8 | readl(USB3_PHY_REVISION_ID0);
+}
diff --git a/platform/thulium/thulium-clock.c b/platform/thulium/thulium-clock.c
index ae1d0de..c759df1 100644
--- a/platform/thulium/thulium-clock.c
+++ b/platform/thulium/thulium-clock.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
@@ -185,13 +185,13 @@
 	},
 };
 
-static struct vote_clk gcc_blsp1_ahb_clk = {
-	.cbcr_reg     = (uint32_t *) BLSP1_AHB_CBCR,
+static struct vote_clk gcc_blsp2_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) BLSP2_AHB_CBCR,
 	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
-	.en_mask      = BIT(17),
+	.en_mask      = BIT(15),
 
 	.c = {
-		.dbg_name = "gcc_blsp1_ahb_clk",
+		.dbg_name = "gcc_blsp2_ahb_clk",
 		.ops      = &clk_ops_vote,
 	},
 };
@@ -204,9 +204,9 @@
 	F( 20000000,  gpll0,  15,   1,   2),
 	F( 25000000,  gpll0,  12,   1,   2),
 	F( 50000000,  gpll0,  12,   0,   0),
-	F( 96000000,  gpll4,  16,   0,   0),
-	F(192000000,  gpll4,   8,   0,   0),
-	F(384000000,  gpll4,   4,   0,   0),
+	F( 96000000,  gpll4,   4,   0,   0),
+	F(192000000,  gpll4,   2,   0,   0),
+	F(384000000,  gpll4,   1,   0,   0),
 	F_END
 };
 
@@ -261,7 +261,9 @@
 };
 
 static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
-	F( 125000000, gpll0,    1,    5,    24),
+	F(  19200000, gpll0,    1,    0,    0),
+	F( 125000000, gpll0,    5,    0,    0),
+	F( 150000000, gpll0,    4,    0,    0),
 	F_END
 };
 
@@ -398,7 +400,7 @@
 	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
 	CLK_LOOKUP("sdc1_core_clk",  gcc_sdcc1_apps_clk.c),
 
-	CLK_LOOKUP("uart8_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("uart8_iface_clk", gcc_blsp2_ahb_clk.c),
 	CLK_LOOKUP("uart8_core_clk",  gcc_blsp2_uart2_apps_clk.c),
 
 	/* USB30 clocks */
diff --git a/project/msm8994.mk b/project/msm8994.mk
index ca88edd..f70dbe9 100644
--- a/project/msm8994.mk
+++ b/project/msm8994.mk
@@ -64,6 +64,8 @@
 
 ifeq ($(ENABLE_MDTP_SUPPORT),1)
 DEFINES += MDTP_SUPPORT=1
+DEFINES += MDTP_EFUSE_ADDRESS=0xFC4B81F8 # QFPROM_RAW_SPARE_REG19_LSB
+DEFINES += MDTP_EFUSE_START=17
 endif
 
 # Turn on Werror
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index ac0acb9..7ba0cd6 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -240,7 +240,7 @@
 	{
 		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, SDC1_HDRV_PULL_CTL },
 		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, SDC1_HDRV_PULL_CTL },
-		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_6MA, TLMM_HDRV_MASK, SDC1_HDRV_PULL_CTL },
+		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, SDC1_HDRV_PULL_CTL },
 	};
 
 	/* Pull configs for sdc pins */
diff --git a/target/msm8916/include/target/display.h b/target/msm8916/include/target/display.h
index 620816f..d3aec0f 100644
--- a/target/msm8916/include/target/display.h
+++ b/target/msm8916/include/target/display.h
@@ -41,6 +41,10 @@
   "msmgpio", 25, 3, 1, 0, 1
 };
 
+static struct gpio_pin reset_gpio = {
+  "msmgpio", 12, 3, 1, 0, 1
+};
+
 static struct gpio_pin enable_gpio = {
   "msmgpio", 97, 3, 1, 0, 1
 };
@@ -148,6 +152,7 @@
 {
 	HW_PLATFORM_SUBTYPE_DEFAULT = 0,
 	HW_PLATFORM_SUBTYPE_CDP_1 = 1,
+	HW_PLATFORM_SUBTYPE_CDP_2 = 2,
 	HW_PLATFORM_SUBTYPE_MTP_3 = 3,
 	HW_PLATFORM_SUBTYPE_SKUH = 4,
 	HW_PLATFORM_SUBTYPE_SKUI = 5, /* msm8916 */
@@ -172,6 +177,8 @@
 	SAMSUNG_WXGA_VIDEO_PANEL,
 	HX8279A_WSVGA_VIDEO_PANEL,
 	R61318_HD_VIDEO_PANEL,
+	R63417_1080P_VIDEO_PANEL,
+	JDI_A216_FHD_VIDEO_PANEL,
 	UNKNOWN_PANEL
 };
 
diff --git a/target/msm8916/oem_panel.c b/target/msm8916/oem_panel.c
index af82460..2d6a19c 100644
--- a/target/msm8916/oem_panel.c
+++ b/target/msm8916/oem_panel.c
@@ -56,6 +56,8 @@
 #include "include/panel_samsung_wxga_video.h"
 #include "include/panel_hx8279a_wsvga_video.h"
 #include "include/panel_r61318_hd_video.h"
+#include "include/panel_r63417_1080p_video.h"
+#include "include/panel_jdi_a216_fhd_video.h"
 
 #define DISPLAY_MAX_PANEL_DETECTION 2
 #define OTM8019A_FWVGA_VIDEO_PANEL_ON_DELAY 50
@@ -91,6 +93,8 @@
 	{"samsung_wxga_video", SAMSUNG_WXGA_VIDEO_PANEL},
 	{"hx8279a_wsvga_video", HX8279A_WSVGA_VIDEO_PANEL},
 	{"r61318_hd_video", R61318_HD_VIDEO_PANEL},
+	{"r63417_1080p_video", R63417_1080P_VIDEO_PANEL},
+	{"jdi_a216_fhd_video", JDI_A216_FHD_VIDEO_PANEL},
 };
 
 static uint32_t panel_id;
@@ -500,6 +504,50 @@
 		memcpy(phy_db->timing,
 				 r61318_hd_video_timings, TIMING_SIZE);
 		break;
+	case R63417_1080P_VIDEO_PANEL:
+		panelstruct->paneldata    = & r63417_1080p_video_panel_data;
+		panelstruct->panelres     = & r63417_1080p_video_panel_res;
+		panelstruct->color        = & r63417_1080p_video_color;
+		panelstruct->videopanel   = & r63417_1080p_video_video_panel;
+		panelstruct->commandpanel = & r63417_1080p_video_command_panel;
+		panelstruct->state        = & r63417_1080p_video_state;
+		panelstruct->laneconfig   = & r63417_1080p_video_lane_config;
+		panelstruct->paneltiminginfo
+					= & r63417_1080p_video_timing_info;
+		panelstruct->panelresetseq
+					= & r63417_1080p_video_reset_seq;
+		panelstruct->backlightinfo = & r63417_1080p_video_backlight;
+		pinfo->mipi.panel_on_cmds
+					=  r63417_1080p_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+					=  R63417_1080P_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+					= r63417_1080p_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+					= R63417_1080P_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing,
+				r63417_1080p_video_timings, TIMING_SIZE);
+		break;
+	case JDI_A216_FHD_VIDEO_PANEL:
+		panelstruct->paneldata    = &jdi_a216_fhd_video_panel_data;
+		panelstruct->panelres     = &jdi_a216_fhd_video_panel_res;
+		panelstruct->color        = &jdi_a216_fhd_video_color;
+		panelstruct->videopanel   = &jdi_a216_fhd_video_video_panel;
+		panelstruct->commandpanel = &jdi_a216_fhd_video_command_panel;
+		panelstruct->state        = &jdi_a216_fhd_video_state;
+		panelstruct->laneconfig   = &jdi_a216_fhd_video_lane_config;
+		panelstruct->paneltiminginfo
+					  = &jdi_a216_fhd_video_timing_info;
+		panelstruct->panelresetseq
+					  = &jdi_a216_fhd_video_reset_seq;
+		panelstruct->backlightinfo = &jdi_a216_fhd_video_backlight;
+		pinfo->mipi.panel_cmds
+					  = jdi_a216_fhd_video_on_command;
+		pinfo->mipi.num_of_panel_cmds
+					  = JDI_A216_FHD_VIDEO_ON_COMMAND;
+		memcpy(phy_db->timing,
+				jdi_a216_fhd_video_timings, TIMING_SIZE);
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -550,13 +598,31 @@
 
 	switch (hw_id) {
 	case HW_PLATFORM_MTP:
-		panel_id = JDI_1080P_VIDEO_PANEL;
-		if (hw_subtype == HW_PLATFORM_SUBTYPE_MTP_3)
+		if (platform_is_msm8939() &&
+			hw_subtype == HW_PLATFORM_SUBTYPE_MTP_3) {
 			panel_id = JDI_FHD_VIDEO_PANEL;
+		} else {
+			panel_id = JDI_1080P_VIDEO_PANEL;
+			switch (auto_pan_loop) {
+			case 0:
+				panel_id = JDI_1080P_VIDEO_PANEL;
+				break;
+			case 1:
+				panel_id = HX8394D_720P_VIDEO_PANEL;
+				break;
+			default:
+				panel_id = UNKNOWN_PANEL;
+				dprintf(CRITICAL, "Unknown panel\n");
+				return PANEL_TYPE_UNKNOWN;
+			}
+			auto_pan_loop++;
+		}
 		break;
 	case HW_PLATFORM_SURF:
 		if (hw_subtype == HW_PLATFORM_SUBTYPE_CDP_1) {
 			panel_id = JDI_FHD_VIDEO_PANEL;
+		} else if (hw_subtype == HW_PLATFORM_SUBTYPE_CDP_2) {
+			panel_id = JDI_A216_FHD_VIDEO_PANEL;
 		} else {
 			panel_id = JDI_1080P_VIDEO_PANEL;
 			switch (auto_pan_loop) {
@@ -583,6 +649,8 @@
 			case HW_PLATFORM_SUBTYPE_SKUK:
 				if ((plat_hw_ver_major >> 4) == 0x1)
 					panel_id = R61318_HD_VIDEO_PANEL;
+				else if ((plat_hw_ver_major >> 4) == 0x2)
+					panel_id = R63417_1080P_VIDEO_PANEL;
 				else
 					panel_id = NT35596_1080P_VIDEO_PANEL;
 				break;
diff --git a/target/msm8916/target_display.c b/target/msm8916/target_display.c
index fe7357a..17b469c 100644
--- a/target/msm8916/target_display.c
+++ b/target/msm8916/target_display.c
@@ -311,6 +311,18 @@
 	}
 }
 
+int target_panel_reset_jdi_a216(uint8_t enable)
+{
+	if (enable) {
+		gpio_tlmm_config(ts_reset_gpio.pin_id, 0,
+			ts_reset_gpio.pin_direction, ts_reset_gpio.pin_pull,
+			ts_reset_gpio.pin_strength, ts_reset_gpio.pin_state);
+		gpio_set_dir(ts_reset_gpio.pin_id, GPIO_STATE_HIGH);
+	} else {
+		gpio_set_dir(ts_reset_gpio.pin_id, GPIO_STATE_LOW);
+	}
+}
+
 int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
 						struct msm_panel_info *pinfo)
 {
@@ -343,9 +355,14 @@
 			if ((hw_id == HW_PLATFORM_QRD) &&
 				 (hw_subtype == HW_PLATFORM_SUBTYPE_SKUK))
 				target_panel_reset_skuk(enable);
-			if ((hw_subtype == HW_PLATFORM_SUBTYPE_CDP_1) ||
-				 (hw_subtype == HW_PLATFORM_SUBTYPE_MTP_3))
+			if (((hw_id == HW_PLATFORM_SURF) &&
+				(hw_subtype == HW_PLATFORM_SUBTYPE_CDP_1)) ||
+				((hw_id == HW_PLATFORM_MTP) &&
+				 (hw_subtype == HW_PLATFORM_SUBTYPE_MTP_3)))
 				target_panel_reset_incell(enable);
+			if ((hw_id == HW_PLATFORM_SURF) &&
+				(hw_subtype == HW_PLATFORM_SUBTYPE_CDP_2))
+				target_panel_reset_jdi_a216(enable);
 		} else { /* msm8916 */
 			if ((hw_id == HW_PLATFORM_QRD) &&
 				 (hw_subtype == HW_PLATFORM_SUBTYPE_SKUH))
diff --git a/target/msm8994/rules.mk b/target/msm8994/rules.mk
index 3637a57..9c02201 100644
--- a/target/msm8994/rules.mk
+++ b/target/msm8994/rules.mk
@@ -16,6 +16,8 @@
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
 
+DEFINES += DISPLAY_EN_20NM_PLL_90_PHASE
+
 MODULES += \
 	dev/keys \
 	dev/pmic/pm8x41 \
diff --git a/target/thulium/init.c b/target/thulium/init.c
index 74646b1..6f2a568 100644
--- a/target/thulium/init.c
+++ b/target/thulium/init.c
@@ -106,7 +106,7 @@
 	thread_sleep(1);
 
 	/* Get status of P_GPIO_5 */
-	pm8x41_gpio_get(3, &status);
+	pm8x41_gpio_get(2, &status);
 
 	return !status; /* active low */
 }
@@ -176,6 +176,7 @@
 
 	config.bus_width = DATA_BUS_WIDTH_8BIT;
 	config.max_clk_rate = MMC_CLK_192MHZ;
+	config.hs400_support = 1;
 
 	/* Try slot 1*/
 	config.slot = 1;
@@ -259,7 +260,10 @@
 
 	switch(platform) {
 	case MSMTHULIUM:
-		board->baseband = BASEBAND_MSM;
+		if (board->platform_version == 0x10000)
+			board->baseband = BASEBAND_APQ;
+		else
+			board->baseband = BASEBAND_MSM;
 		break;
 	default:
 		dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);