Merge "dev: gcdb: display: add support for hx8399c fhd+ video mode panel"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index c04b504..7a63036 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2018, 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:
@@ -272,9 +272,10 @@
 struct getvar_partition_info part_info[NUM_PARTITIONS];
 struct getvar_partition_info part_type_known[] =
 {
-	{ "system"  , "partition-size:", "partition-type:", "", "ext4" },
-	{ "userdata", "partition-size:", "partition-type:", "", "ext4" },
-	{ "cache"   , "partition-size:", "partition-type:", "", "ext4" },
+	{ "system"     , "partition-size:", "partition-type:", "", "ext4" },
+	{ "userdata"   , "partition-size:", "partition-type:", "", "ext4" },
+	{ "cache"      , "partition-size:", "partition-type:", "", "ext4" },
+	{ "recoveryfs" , "partition-size:", "partition-type:", "", "ext4" },
 };
 
 char max_download_size[MAX_RSP_SIZE];
@@ -1915,9 +1916,9 @@
 	unsigned long long ptn = 0;
 	unsigned long long size;
 	int index = INVALID_PTN;
-	uint32_t blocksize;
 	uint8_t lun = 0;
 	uint32_t ret = 0;
+	uint32_t device_info_sz = 0;
 
 	if (devinfo_present)
 		index = partition_get_index("devinfo");
@@ -1935,12 +1936,18 @@
 
 	size = partition_get_size(index);
 
-	blocksize = mmc_get_device_blocksize();
+	device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
+							mmc_blocksize_mask);
+	if (device_info_sz == UINT_MAX)
+	{
+		dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
+		return;
+	}
 
 	if (devinfo_present)
-		ret = mmc_write(ptn, blocksize, (void *)info_buf);
+		ret = mmc_write(ptn, device_info_sz, (void *)info_buf);
 	else
-		ret = mmc_write((ptn + size - blocksize), blocksize, (void *)info_buf);
+		ret = mmc_write((ptn + size - device_info_sz), device_info_sz, (void *)info_buf);
 	if (ret)
 	{
 		dprintf(CRITICAL, "ERROR: Cannot write device info\n");
@@ -1953,8 +1960,8 @@
 	unsigned long long ptn = 0;
 	unsigned long long size;
 	int index = INVALID_PTN;
-	uint32_t blocksize;
 	uint32_t ret  = 0;
+	uint32_t device_info_sz = 0;
 
 	if ((index = partition_get_index("devinfo")) < 0)
 	{
@@ -1972,12 +1979,18 @@
 
 	size = partition_get_size(index);
 
-	blocksize = mmc_get_device_blocksize();
+	device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
+							mmc_blocksize_mask);
+	if (device_info_sz == UINT_MAX)
+	{
+		dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
+		return;
+	}
 
 	if (devinfo_present)
-		ret = mmc_read(ptn, (void *)info_buf, blocksize);
+		ret = mmc_read(ptn, (void *)info_buf, device_info_sz);
 	else
-		ret = mmc_read((ptn + size - blocksize), (void *)info_buf, blocksize);
+		ret = mmc_read((ptn + size - device_info_sz), (void *)info_buf, device_info_sz);
 	if (ret)
 	{
 		dprintf(CRITICAL, "ERROR: Cannot read device info\n");
@@ -2803,6 +2816,92 @@
 		cmd_erase_nand(arg, data, sz);
 }
 
+/* Get the size from partiton name */
+static void get_partition_size(const char *arg, char *response)
+{
+	uint64_t ptn = 0;
+	uint64_t size;
+	int index = INVALID_PTN;
+
+	index = partition_get_index(arg);
+
+	if (index == INVALID_PTN)
+	{
+		dprintf(CRITICAL, "Invalid partition index\n");
+		return;
+	}
+
+	ptn = partition_get_offset(index);
+
+	if(!ptn)
+	{
+		dprintf(CRITICAL, "Invalid partition name %s\n", arg);
+		return;
+	}
+
+	size = partition_get_size(index);
+
+	snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
+	return;
+}
+
+/*
+ * Publish the partition type & size info
+ * fastboot getvar will publish the required information.
+ * fastboot getvar partition_size:<partition_name>: partition size in hex
+ * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
+ */
+static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
+{
+	uint8_t i,n;
+	static bool published = false;
+	struct partition_entry *ptn_entry =
+				partition_get_partition_entries();
+	memset(info, 0, sizeof(struct getvar_partition_info)* num_parts);
+
+	for (i = 0; i < num_parts; i++) {
+		strlcat(info[i].part_name, (const char *)ptn_entry[i].name, MAX_RSP_SIZE);
+		strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
+		strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
+
+		/* Mark partiton type for known paritions only */
+		for (n=0; n < ARRAY_SIZE(part_type_known); n++)
+		{
+			if (!strncmp(part_type_known[n].part_name, info[i].part_name,
+					strlen(part_type_known[n].part_name)))
+			{
+				strlcat(info[i].type_response,
+						part_type_known[n].type_response,
+						MAX_RSP_SIZE);
+				break;
+			}
+		}
+
+		get_partition_size(info[i].part_name, info[i].size_response);
+
+		if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
+		{
+			dprintf(CRITICAL, "partition size name truncated\n");
+			return;
+		}
+		if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
+		{
+			dprintf(CRITICAL, "partition type name truncated\n");
+			return;
+		}
+
+		if (!published)
+		{
+			/* publish partition size & type info */
+			fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
+			fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
+		}
+	}
+	if (!published)
+		published = true;
+}
+
+
 void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
 {
 	unsigned long long ptn = 0;
@@ -2847,6 +2946,8 @@
 				fastboot_fail("failed to write partition");
 				return;
 			}
+			/* Re-publish partition table */
+			publish_getvar_partition_info(part_info, partition_get_partition_count());
 
 			/* Rescan partition table to ensure we have multislot support*/
 			if (partition_scan_for_multislot())
@@ -3969,84 +4070,6 @@
 	}
 }
 
-/* Get the size from partiton name */
-static void get_partition_size(const char *arg, char *response)
-{
-	uint64_t ptn = 0;
-	uint64_t size;
-	int index = INVALID_PTN;
-
-	index = partition_get_index(arg);
-
-	if (index == INVALID_PTN)
-	{
-		dprintf(CRITICAL, "Invalid partition index\n");
-		return;
-	}
-
-	ptn = partition_get_offset(index);
-
-	if(!ptn)
-	{
-		dprintf(CRITICAL, "Invalid partition name %s\n", arg);
-		return;
-	}
-
-	size = partition_get_size(index);
-
-	snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
-	return;
-}
-
-/*
- * Publish the partition type & size info
- * fastboot getvar will publish the required information.
- * fastboot getvar partition_size:<partition_name>: partition size in hex
- * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
- */
-static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
-{
-	uint8_t i,n;
-	struct partition_entry *ptn_entry =
-				partition_get_partition_entries();
-
-	for (i = 0; i < num_parts; i++) {
-		strlcat(info[i].part_name, (char const *)ptn_entry[i].name, MAX_RSP_SIZE);
-		strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
-		strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
-
-		/* Mark partiton type for known paritions only */
-		for (n=0; n < ARRAY_SIZE(part_type_known); n++)
-		{
-			if (!strncmp(part_type_known[n].part_name, info[i].part_name,
-					strlen(part_type_known[n].part_name)))
-			{
-				strlcat(info[i].type_response,
-						part_type_known[n].type_response,
-						MAX_RSP_SIZE);
-				break;
-			}
-		}
-
-		get_partition_size(info[i].part_name, info[i].size_response);
-
-		if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
-		{
-			dprintf(CRITICAL, "partition size name truncated\n");
-			return;
-		}
-		if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
-		{
-			dprintf(CRITICAL, "partition type name truncated\n");
-			return;
-		}
-
-		/* publish partition size & type info */
-		fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
-		fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
-	}
-}
-
 void publish_getvar_multislot_vars()
 {
 	int i,count;
diff --git a/app/tests/rules.mk b/app/tests/rules.mk
index ec79a7f..1b3d15b 100644
--- a/app/tests/rules.mk
+++ b/app/tests/rules.mk
@@ -5,6 +5,7 @@
 OBJS += \
 	$(LOCAL_DIR)/tests.o \
 	$(LOCAL_DIR)/thread_tests.o \
+	$(LOCAL_DIR)/spi_test.o \
 	$(LOCAL_DIR)/printf_tests.o
 
 ifeq ($(VERIFIED_BOOT),1)
diff --git a/app/tests/spi_test.c b/app/tests/spi_test.c
new file mode 100755
index 0000000..582496e
--- /dev/null
+++ b/app/tests/spi_test.c
@@ -0,0 +1,65 @@
+/* Copyright (c) 2017-2018, 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, Inc. 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 <spi_qup.h>
+#include <blsp_qup.h>
+#include <stdlib.h>
+
+void spi_test()
+{
+	unsigned char *tx_buf1;
+	unsigned int data_size = 240*320*2;
+	struct qup_spi_dev *spi_dev;
+	int i,j,k;
+
+	dprintf(CRITICAL, "-----start %s----\n", __func__);
+
+	tx_buf1 = malloc(data_size);
+
+	k = 0;
+	for (i = 0; i < 320; i++) {
+		for (j = 0; j < 240; j++) {
+			tx_buf1[k] = 0xf8;
+			tx_buf1[k+1] = 0x00;
+			k = k+2;
+		}
+	}
+
+	spi_dev = qup_blsp_spi_init(BLSP_ID_1, QUP_ID_4);
+
+	if (!spi_dev) {
+		dprintf(CRITICAL, "Failed initializing SPI\n");
+		return;
+	}
+
+	spi_qup_transfer(spi_dev, tx_buf1, data_size);
+
+	free(tx_buf1);
+	dprintf(CRITICAL, "-----end %s----\n", __func__);
+}
diff --git a/dev/fbcon/fbcon.c b/dev/fbcon/fbcon.c
index 5bce3c2..adc5e29 100644
--- a/dev/fbcon/fbcon.c
+++ b/dev/fbcon/fbcon.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2015, 2018 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
@@ -504,7 +504,6 @@
 	image_base = ((((total_y/2) - (SPLASH_IMAGE_HEIGHT / 2) - 1) *
 			(config->width)) + (total_x/2 - (SPLASH_IMAGE_WIDTH / 2)));
 
-#if DISPLAY_TYPE_MIPI
 #if ENABLE_WBC
 	image = (pm_appsbl_charging_in_progress() ? image_batt888 : imageBuffer_rgb888);
 #else
@@ -518,13 +517,6 @@
 			SPLASH_IMAGE_WIDTH * bytes_per_bpp);
 		}
 	}
-	fbcon_flush();
-#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
-	if(is_cmd_mode_enabled())
-		mipi_dsi_cmd_mode_trigger();
-#endif
-
-#else
 
 	if (bytes_per_bpp == 2) {
 		for (i = 0; i < SPLASH_IMAGE_HEIGHT; i++) {
@@ -533,7 +525,12 @@
 			SPLASH_IMAGE_WIDTH * bytes_per_bpp);
 		}
 	}
+
 	fbcon_flush();
+
+#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
+	if(is_cmd_mode_enabled())
+		mipi_dsi_cmd_mode_trigger();
 #endif
 }
 
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index 945839c..9cde84a 100644
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018 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
@@ -486,6 +486,53 @@
 			~USE_DSI1_PLL_FLAG;
 }
 
+static int mdss_spi_bl_enable(uint8_t enable)
+{
+	int ret = NO_ERROR;
+
+	ret = panel_backlight_ctrl(enable);
+	if (ret)
+		dprintf(CRITICAL, "Backlight %s failed\n", enable ? "enable" : "disable");
+	return ret;
+}
+
+static int mdss_spi_panel_power(uint8_t enable, struct msm_panel_info *pinfo)
+{
+	int ret = NO_ERROR;
+
+	if (enable) {
+		ret = target_ldo_ctrl(enable, pinfo);
+		if (ret) {
+			dprintf(CRITICAL, "LDO control enable failed\n");
+			return ret;
+		}
+
+		/*Panel Reset*/
+		ret = target_panel_reset(enable,panelstruct.panelresetseq, &panel.panel_info);
+		if (ret) {
+			dprintf(CRITICAL, "panel reset failed\n");
+			return ret;
+		}
+		dprintf(INFO, "Panel power on done\n");
+	} else {
+		/*Disable panel and ldo*/
+		ret = target_panel_reset(enable, panelstruct.panelresetseq, &panel.panel_info);
+		if (ret) {
+			dprintf(CRITICAL, "panel reset disable failed \n");
+			return ret;
+		}
+
+		ret = target_ldo_ctrl(enable, pinfo);
+		if (ret) {
+			dprintf(CRITICAL, "panel reset disable failed \n");
+			return ret;
+		}
+		dprintf(INFO, "Panel power off done\n");
+	}
+
+	return ret;
+}
+
 static int update_dsi_display_config()
 {
 	int ret = NO_ERROR;
@@ -566,6 +613,18 @@
                 panel.power_func = mdss_edp_panel_power;
 		panel.bl_func = mdss_edp_bl_enable;
                 panel.fb.format = FB_FORMAT_RGB888;
+	} else if (pan_type == PANEL_TYPE_SPI) {
+		panel.panel_info.xres = panelstruct.panelres->panel_width;
+		panel.panel_info.yres = panelstruct.panelres->panel_height;
+		panel.panel_info.bpp = panelstruct.color->color_format;
+		panel.power_func = mdss_spi_panel_power;
+		panel.bl_func = mdss_spi_bl_enable;
+		panel.fb.base = base;
+		panel.fb.width = panel.panel_info.xres;
+		panel.fb.height = panel.panel_info.yres;
+		panel.fb.bpp = panel.panel_info.bpp;
+		panel.fb.format = FB_FORMAT_RGB565;
+		panel.panel_info.type = SPI_PANEL;
 	} else {
 		dprintf(CRITICAL, "Target panel init not found!\n");
 		ret = ERR_NOT_SUPPORTED;
diff --git a/dev/gcdb/display/include/panel.h b/dev/gcdb/display/include/panel.h
old mode 100755
new mode 100644
index 3a83bce..1c83c6d
--- a/dev/gcdb/display/include/panel.h
+++ b/dev/gcdb/display/include/panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 2018, 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
@@ -48,7 +48,8 @@
 	PANEL_TYPE_UNKNOWN,
 	PANEL_TYPE_DSI,
 	PANEL_TYPE_EDP,
-	PANEL_TYPE_HDMI
+	PANEL_TYPE_HDMI,
+	PANEL_TYPE_SPI
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_st7789v2_qvga_spi_cmd.h b/dev/gcdb/display/include/panel_st7789v2_qvga_spi_cmd.h
new file mode 100644
index 0000000..869f536
--- /dev/null
+++ b/dev/gcdb/display/include/panel_st7789v2_qvga_spi_cmd.h
@@ -0,0 +1,206 @@
+/* Copyright (c) 2017-2018, 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_ST7789v2_QVGA_SPI_CMD_H_
+#define _PANEL_ST7789v2_QVGA_SPI_CMD_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config st7789v2_qvga_cmd_panel_data = {
+	"qcom,mdss_spi_st7789v2_qvga_cmd", "spi:0:", "qcom,mdss-spi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution st7789v2_qvga_cmd_panel_res = {
+	240, 240, 79, 59, 60, 0, 7, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info st7789v2_qvga_cmd_color = {
+	16, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char st7789v2_qvga_cmd_on_cmd0[] = {
+	0x11,
+};
+
+static char st7789v2_qvga_cmd_on_cmd1[] = {
+	0x36, 0x00,
+};
+
+static char st7789v2_qvga_cmd_on_cmd2[] = {
+	0x3A, 0x05,
+};
+
+static char st7789v2_qvga_cmd_on_cmd3[] = {
+	0x35, 0x00,
+};
+
+static char st7789v2_qvga_cmd_on_cmd4[] = {
+	0xB2, 0x0C, 0x0C, 0x00,
+	0x33, 0x33,
+};
+
+static char st7789v2_qvga_cmd_on_cmd5[] = {
+	0xB7, 0x75,
+};
+
+static char st7789v2_qvga_cmd_on_cmd6[] = {
+	0xBB, 0x3D,
+};
+
+static char st7789v2_qvga_cmd_on_cmd7[] = {
+	0xC2, 0x01,
+};
+
+static char st7789v2_qvga_cmd_on_cmd8[] = {
+	0xC3, 0x19,
+};
+
+static char st7789v2_qvga_cmd_on_cmd9[] = {
+	0x04, 0x20,
+};
+
+static char st7789v2_qvga_cmd_on_cmd10[] = {
+	0xc6, 0x0F,
+};
+
+static char st7789v2_qvga_cmd_on_cmd11[] = {
+	0xD0, 0xA4, 0xA1,
+};
+
+static char st7789v2_qvga_cmd_on_cmd12[] = {
+	0xE0, 0x70, 0x04, 0x08,
+	0x09, 0x09, 0x05, 0x2A,
+	0x33, 0x41, 0x07, 0x13,
+	0x13, 0x29, 0x2F,
+};
+
+static char st7789v2_qvga_cmd_on_cmd13[] = {
+	0xE1, 0x70, 0x03, 0x09,
+	0x0A, 0x09, 0x06, 0x2B,
+	0x34, 0x41, 0x07, 0x12,
+	0x14, 0x28, 0x2E
+};
+
+static char st7789v2_qvga_cmd_on_cmd14[] = {
+	0x21,
+};
+
+static char st7789v2_qvga_cmd_on_cmd15[] = {
+	0x29,
+};
+
+static char st7789v2_qvga_cmd_on_cmd16[] = {
+	0x2A, 0x00, 0x00, 0x00, 0xEF
+};
+
+static char st7789v2_qvga_cmd_on_cmd17[] = {
+	0x2B, 0x00, 0x00, 0x00, 0xEF
+};
+
+static char st7789v2_qvga_cmd_on_cmd18[] = {
+	0x2c
+};
+
+static struct mdss_spi_cmd st7789v2_qvga_cmd_on_command[] = {
+	{0x01, st7789v2_qvga_cmd_on_cmd0, 0x78, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd1, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd2, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd3, 0x00, 0},
+	{0x06, st7789v2_qvga_cmd_on_cmd4, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd5, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd6, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd7, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd8, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd9, 0x00, 0},
+	{0x02, st7789v2_qvga_cmd_on_cmd10, 0x00, 0},
+	{0x03, st7789v2_qvga_cmd_on_cmd11, 0x00, 0},
+	{0x0F, st7789v2_qvga_cmd_on_cmd12, 0x00, 0},
+	{0x0F, st7789v2_qvga_cmd_on_cmd13, 0x00, 0},
+	{0x01, st7789v2_qvga_cmd_on_cmd14, 0x00, 0},
+	{0x01, st7789v2_qvga_cmd_on_cmd15, 0x78, 0},
+	{0x05, st7789v2_qvga_cmd_on_cmd16, 0x00, 0},
+	{0x05, st7789v2_qvga_cmd_on_cmd17, 0x00, 0},
+	{0x01, st7789v2_qvga_cmd_on_cmd18, 0x00, 0},
+};
+
+#define ST7789v2_QVGA_CMD_ON_COMMAND 19
+
+
+static char st7789v2_qvga_cmdoff_cmd0[] = {
+	0x28,
+};
+
+static char st7789v2_qvga_cmdoff_cmd1[] = {
+	0x10,
+};
+
+static struct mipi_dsi_cmd st7789v2_qvga_cmd_off_command[] = {
+	{0x1, st7789v2_qvga_cmdoff_cmd0, 0x20},
+	{0x1, st7789v2_qvga_cmdoff_cmd1, 0x20}
+};
+
+#define ST7789v2_QVGA_CMD_OFF_COMMAND 2
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence st7789v2_qvga_cmd_reset_seq = {
+	{1, 0, 1, }, {20, 2, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight st7789v2_qvga_cmd_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+static uint8_t st7789v2_signature_addr = 0x04;
+
+static uint8_t st7789v2_signature_len = 3;
+
+static uint8_t st7789v2_signature[] = {
+	0x85, 0x85, 0x52
+};
+
+#endif /* PANEL_ST7789v2_QVGA_SPI_CMD_H */
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 5b1c20e..0fc517b 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017-2018, 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
@@ -223,6 +223,7 @@
 uint32_t pm8x41_resin_status();
 void pm8x41_reset_configure(uint8_t);
 void pm8994_reset_configure(uint8_t);
+void pmi632_reset_configure(uint8_t);
 void pm8x41_v2_reset_configure(uint8_t);
 uint8_t pmi8950_get_pmi_subtype();
 int pm8x41_ldo_set_voltage(struct pm8x41_ldo *ldo, uint32_t voltage);
diff --git a/dev/pmic/pm8x41/include/pm_vib.h b/dev/pmic/pm8x41/include/pm_vib.h
index 9b10327..d072d69 100644
--- a/dev/pmic/pm8x41/include/pm_vib.h
+++ b/dev/pmic/pm8x41/include/pm_vib.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2017-2018, 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
@@ -35,4 +35,10 @@
 
 void pm_vib_turn_on(void);
 void pm_vib_turn_off(void);
+
+void pm_vib_ldo_turn_on(void);
+void pm_vib_ldo_turn_off(void);
+
+void pm_haptic_vib_turn_on(void);
+void pm_haptic_vib_turn_off(void);
 #endif/* __DEV_PMIC_VIB_VIBRATOR_H */
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 0c389eb..442bc35 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017-2018, 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
@@ -389,6 +389,40 @@
 		return 0;
 }
 
+void pmi632_reset_configure(uint8_t reset_type)
+{
+	/* Slave ID of pm8953 and pmi632 */
+	uint8_t slave_id[] = {0, 2};
+	uint8_t i;
+
+	/* Reset sequence
+	1. Disable the ps hold for pm8953 and pmi632
+	2. set reset type for both pm8953 & pmi632
+	3. Enable ps hold for pm8953 to trigger the reset
+	*/
+	/* disable PS_HOLD_RESET */
+	pm8xxx_reg_write(slave_id[0], PON_PS_HOLD_RESET_CTL2, 0x0);
+	pm8xxx_reg_write(slave_id[1], PON_PS_HOLD_RESET_CTL2, 0x0);
+
+	/* Delay needed for disable to kick in. */
+	udelay(300);
+
+	/* configure reset type */
+	for (i = 0; i < ARRAY_SIZE(slave_id); i++)
+		pm8xxx_reg_write(slave_id[i], PON_PS_HOLD_RESET_CTL, reset_type);
+
+	if (reset_type == PON_PSHOLD_WARM_RESET)
+	{
+		/* enable PS_HOLD_RESET */
+		for (i = 0; i < ARRAY_SIZE(slave_id); i++)
+			pm8xxx_reg_write(slave_id[i], PON_PS_HOLD_RESET_CTL2, BIT(S2_RESET_EN_BIT));
+	}
+	else
+	{
+			pm8xxx_reg_write(slave_id[0], PON_PS_HOLD_RESET_CTL2, BIT(S2_RESET_EN_BIT));
+	}
+}
+
 void pm8994_reset_configure(uint8_t reset_type)
 {
 	/* Slave ID of pm8994 and pmi8994 */
diff --git a/dev/qpnp_haptic/qpnp_haptic.c b/dev/qpnp_haptic/qpnp_haptic.c
index a4e3820..ec91d2a 100644
--- a/dev/qpnp_haptic/qpnp_haptic.c
+++ b/dev/qpnp_haptic/qpnp_haptic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2017-2018, 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
@@ -83,7 +83,7 @@
 #define QPNP_HAP_LRA_AUTO_MASK 0x70
 
 /* Turn on vibrator */
-void pm_vib_turn_on(void)
+void pm_haptic_vib_turn_on(void)
 {
 	struct qpnp_hap vib_config = {0};
 
@@ -150,7 +150,7 @@
 }
 
 /* Turn off vibrator */
-void pm_vib_turn_off(void)
+void pm_haptic_vib_turn_off(void)
 {
 	if(!target_is_pmi_enabled())
 		return;
diff --git a/dev/qpnp_haptic/qpnp_vib.c b/dev/qpnp_haptic/qpnp_vib.c
new file mode 100644
index 0000000..fecb794
--- /dev/null
+++ b/dev/qpnp_haptic/qpnp_vib.c
@@ -0,0 +1,46 @@
+/* Copyright (c) 2018, 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 <pm_vib.h>
+#include <board.h>
+
+void pm_vib_turn_on()
+{
+	if ((board_pmic_target(1) & 0xffff) == PMIC_IS_PMI632)
+		pm_vib_ldo_turn_on();
+	else
+		pm_haptic_vib_turn_on();
+}
+
+void pm_vib_turn_off()
+{
+	if ((board_pmic_target(1) & 0xffff) == PMIC_IS_PMI632)
+		pm_vib_ldo_turn_off();
+	else
+		pm_haptic_vib_turn_off();
+}
diff --git a/dev/qpnp_haptic/qpnp_vib_ldo.c b/dev/qpnp_haptic/qpnp_vib_ldo.c
new file mode 100644
index 0000000..7b327cf
--- /dev/null
+++ b/dev/qpnp_haptic/qpnp_vib_ldo.c
@@ -0,0 +1,143 @@
+/* Copyright (c) 2018, 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 <kernel/timer.h>
+#include <qtimer.h>
+#include <bits.h>
+#include <debug.h>
+#include <smem.h>
+#include <spmi.h>
+#include <platform/iomap.h>
+#include <board.h>
+#include <target.h>
+#include <pm_vib.h>
+
+#define VIB_LDO_BASE			(PMI_SECOND_SLAVE_ADDR_BASE + 0x5700)
+#define QPNP_VIB_LDO_STATUS1_REG	(VIB_LDO_BASE + 0x08)
+#define QPNP_VIB_LDO_VSET_LB_REG	(VIB_LDO_BASE + 0x40)
+#define QPNP_VIB_LDO_VSET_UB_REG	(VIB_LDO_BASE + 0x41)
+#define QPNP_VIB_LDO_EN_CTL_REG		(VIB_LDO_BASE + 0x46)
+
+#define QPNP_VIB_LDO_VSET_LB_MASK	0xFF
+#define QPNP_VIB_LDO_VSET_UB_MASK	0xFF
+#define QPNP_VIB_LDO_EN_CTL_MASK	0x80
+#define QPNP_VIB_LDO_EN			0x80
+#define QPNP_VIB_LDO_DIS		0x00
+
+#define VREG_READY BIT(7)
+
+#define MAX_WAIT_FOR_VREG_READY_US	1000
+#define VREG_READY_STEP_DELAY_US	100
+#define VIB_LDO_OVERDRIVE_VOLTAGE_MV	3000
+#define VIB_LDO_NOMINAL_VOLTAGE_MV	1500
+#define OVERDRIVE_TIME_US		30000
+
+/* Turn on vibrator */
+void pm_vib_ldo_turn_on(void)
+{
+	uint8_t status;
+	uint8_t vreg_timer_count = 0;
+
+	if (!target_is_pmi_enabled())
+		return;
+
+	/* Set overdrive voltage*/
+	pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_LB_REG,
+				QPNP_VIB_LDO_VSET_LB_MASK,
+				(VIB_LDO_OVERDRIVE_VOLTAGE_MV & 0xff));
+	pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_UB_REG,
+				QPNP_VIB_LDO_VSET_UB_MASK,
+				((VIB_LDO_OVERDRIVE_VOLTAGE_MV >> 8) & 0xff));
+
+	/* Set Register VIB_LDO_EN_CTL to enable vibrator */
+	pmic_spmi_reg_mask_write(QPNP_VIB_LDO_EN_CTL_REG,
+				QPNP_VIB_LDO_EN_CTL_MASK,
+				QPNP_VIB_LDO_EN);
+
+	/* Wait for VREG_READY*/
+	while (1) {
+		status = pmic_spmi_reg_read(QPNP_VIB_LDO_STATUS1_REG);
+		if ( status & VREG_READY ) {
+			break;
+		}
+		else if ( vreg_timer_count < (MAX_WAIT_FOR_VREG_READY_US /
+						VREG_READY_STEP_DELAY_US) ) {
+			vreg_timer_count++;
+			udelay(VREG_READY_STEP_DELAY_US);
+		}
+		else {
+			dprintf(CRITICAL, "LDO failed to start in 1 msec, "
+				"turning off vibrator\n");
+			pm_vib_ldo_turn_off();
+			return;
+		}
+	}
+
+	udelay(OVERDRIVE_TIME_US);
+
+	/* Set normal voltage */
+	pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_LB_REG,
+				QPNP_VIB_LDO_VSET_LB_MASK,
+				(VIB_LDO_NOMINAL_VOLTAGE_MV & 0xff));
+	pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_UB_REG,
+				QPNP_VIB_LDO_VSET_UB_MASK,
+				((VIB_LDO_NOMINAL_VOLTAGE_MV >> 8) & 0xff));
+
+	vreg_timer_count = 0;
+	/* Wait for VREG_READY*/
+	while (1) {
+		status = pmic_spmi_reg_read(QPNP_VIB_LDO_STATUS1_REG);
+		if ( status & VREG_READY ) {
+			break;
+		}
+		else if ( vreg_timer_count < (MAX_WAIT_FOR_VREG_READY_US /
+						VREG_READY_STEP_DELAY_US) ) {
+			vreg_timer_count++;
+			udelay(VREG_READY_STEP_DELAY_US);
+		}
+		else {
+			dprintf(CRITICAL, "LDO failed to start in 1 msec, "
+				"turning off vibrator\n");
+			pm_vib_ldo_turn_off();
+			return;
+		}
+	}
+
+}
+
+/* Turn off vibrator */
+void pm_vib_ldo_turn_off(void)
+{
+	if (!target_is_pmi_enabled())
+		return;
+
+	/* Clear Register VIB_LDO_EN_CTL to disable vibrator */
+	pmic_spmi_reg_mask_write(QPNP_VIB_LDO_EN_CTL_REG,
+				QPNP_VIB_LDO_EN_CTL_MASK,
+				QPNP_VIB_LDO_DIS);
+}
diff --git a/dev/qpnp_haptic/rules.mk b/dev/qpnp_haptic/rules.mk
index 8922bb7..6beb706 100644
--- a/dev/qpnp_haptic/rules.mk
+++ b/dev/qpnp_haptic/rules.mk
@@ -4,5 +4,7 @@
 
 ifeq ($(ENABLE_HAP_VIB_SUPPORT),true)
 OBJS += \
-	$(LOCAL_DIR)/qpnp_haptic.o
+	$(LOCAL_DIR)/qpnp_vib.o \
+	$(LOCAL_DIR)/qpnp_haptic.o \
+	$(LOCAL_DIR)/qpnp_vib_ldo.o
 endif
diff --git a/lib/heap/heap.c b/lib/heap/heap.c
index 2f41f6c..a4094fb 100644
--- a/lib/heap/heap.c
+++ b/lib/heap/heap.c
@@ -255,6 +255,11 @@
 		size = sizeof(struct free_heap_chunk);
 
 	// round up size to a multiple of native pointer size
+	if(size > (size + sizeof(void *)))
+	{
+		dprintf(CRITICAL, "invalid input size\n");
+		return NULL;
+	}
 	size = ROUNDUP(size, sizeof(void *));
 
 	// deal with nonzero alignments
diff --git a/makefile b/makefile
index f52f698..a1b091e 100644
--- a/makefile
+++ b/makefile
@@ -141,6 +141,12 @@
   DEFINES += USE_LE_SYSTEMD=0
 endif
 
+ifeq ($(MOUNT_EMMC_LE),true)
+  DEFINES += MOUNT_EMMC_LE=1
+else
+  DEFINES += MOUNT_EMMC_LE=0
+endif
+
 #Enable kaslr seed support
 ifeq ($(ENABLE_KASLRSEED),1)
   DEFINES += ENABLE_KASLRSEED_SUPPORT=1
diff --git a/platform/msm8909/acpuclock.c b/platform/msm8909/acpuclock.c
old mode 100644
new mode 100755
index ed2cbfc..48e25ac
--- a/platform/msm8909/acpuclock.c
+++ b/platform/msm8909/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015,2018, 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
@@ -474,3 +474,37 @@
 		return;
 	}
 }
+
+/* Configure spi clock */
+void clock_config_blsp_spi(uint8_t blsp_id, uint8_t qup_id)
+{
+	uint8_t ret = 0;
+	char clk_name[64];
+
+	struct clk *qup_clk;
+	qup_id = qup_id + 1;
+
+	if((blsp_id != BLSP_ID_1)) {
+		dprintf(CRITICAL, "Incorrect BLSP-%d configuration\n", blsp_id);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "blsp1_ahb_iface_clk");
+
+	ret = clk_get_set_enable(clk_name, 0 , 1);
+
+	if (ret) {
+		dprintf(CRITICAL, "%s: Failed to enable %s clock\n", __func__, clk_name);
+		return;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup%u_spi_apps_clk", qup_id);
+
+	/* Set the highest clk frequency by default for good performance. */
+	ret = clk_get_set_enable(clk_name, 50000000, 1);
+
+	if (ret) {
+		dprintf(CRITICAL, "%s: Failed to enable %s\n", __func__, clk_name);
+		return;
+	}
+}
diff --git a/platform/msm8909/gpio.c b/platform/msm8909/gpio.c
old mode 100644
new mode 100755
index 7621bb8..4bd9172
--- a/platform/msm8909/gpio.c
+++ b/platform/msm8909/gpio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014,2018, 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
@@ -141,3 +141,62 @@
 		ASSERT(0);
 	}
 }
+
+void gpio_config_blsp_spi(uint8_t blsp_id, uint8_t qup_id)
+{
+	if(blsp_id == BLSP_ID_1) {
+		switch (qup_id) {
+
+			case QUP_ID_3:
+				/* configure SPI MOSI gpio */
+				gpio_tlmm_config(12, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+
+					/* configure SPI MISO gpio */
+				gpio_tlmm_config(13, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+
+				/* configure SPI CS_N gpio */
+				gpio_tlmm_config(14, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+
+				/* configure SPI CLK gpio */
+				gpio_tlmm_config(15, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+			break;
+
+			case QUP_ID_4:
+				/* configure SPI MOSI gpio */
+				gpio_tlmm_config(16, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+
+					/* configure SPI MISO gpio */
+				gpio_tlmm_config(17, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+
+				/* configure SPI CS_N gpio */
+				gpio_tlmm_config(18, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+
+				/* configure SPI CLK gpio */
+				gpio_tlmm_config(19, 1, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_16MA, GPIO_DISABLE);
+			break;
+
+			case QUP_ID_0:
+			case QUP_ID_1:
+
+			case QUP_ID_2:
+
+
+
+			case QUP_ID_5:
+			default:
+				dprintf(CRITICAL, "Incorrect QUP id %d\n",qup_id);
+				ASSERT(0);
+		};
+	} else {
+		dprintf(CRITICAL, "Incorrect BLSP id %d\n",blsp_id);
+		ASSERT(0);
+	}
+}
diff --git a/platform/msm8909/include/platform/clock.h b/platform/msm8909/include/platform/clock.h
index ce98437..da0f673 100644
--- a/platform/msm8909/include/platform/clock.h
+++ b/platform/msm8909/include/platform/clock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014,2018, 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,4 +76,5 @@
 void mdp_clock_enable(void);
 void mdp_clock_disable(void);
 void mdp_gdsc_ctrl(uint8_t enable);
+void clock_config_blsp_spi(uint8_t blsp_id, uint8_t qup_id);
 #endif
diff --git a/platform/msm8909/include/platform/gpio.h b/platform/msm8909/include/platform/gpio.h
old mode 100644
new mode 100755
index da40c1e..7101bfd
--- a/platform/msm8909/include/platform/gpio.h
+++ b/platform/msm8909/include/platform/gpio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2017-2018, 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
@@ -61,4 +61,5 @@
 #define GPIO_OUT        BIT(1)
 
 void gpio_config_uart_dm(uint8_t id);
+void gpio_config_blsp_spi(uint8_t blsp_id, uint8_t qup_id);
 #endif
diff --git a/platform/msm8909/include/platform/iomap.h b/platform/msm8909/include/platform/iomap.h
old mode 100644
new mode 100755
index 4361afd..f860274
--- a/platform/msm8909/include/platform/iomap.h
+++ b/platform/msm8909/include/platform/iomap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017-2018, 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
@@ -131,6 +131,27 @@
 #define GCC_BLSP1_QUP6_CFG_RCGR     (CLK_CTL_BASE + 0x7004)
 #define GCC_BLSP1_QUP6_CMD_RCGR     (CLK_CTL_BASE + 0x7000)
 
+#define GCC_BLSP1_QUP3_SPI_APPS_CBCR        (CLK_CTL_BASE + 0x401C)
+#define GCC_BLSP1_QUP3_SPI_APPS_CMD_RCGR    (CLK_CTL_BASE + 0x4024)
+#define GCC_BLSP1_QUP3_SPI_CFG_RCGR         (CLK_CTL_BASE + 0x4028)
+#define GCC_BLSP1_QUP3_SPI_APPS_M           (CLK_CTL_BASE + 0x402C)
+#define GCC_BLSP1_QUP3_SPI_APPS_N           (CLK_CTL_BASE + 0x4030)
+#define GCC_BLSP1_QUP3_SPI_APPS_D           (CLK_CTL_BASE + 0x4034)
+
+#define GCC_BLSP1_QUP4_SPI_APPS_CBCR        (CLK_CTL_BASE + 0x501C)
+#define GCC_BLSP1_QUP4_SPI_APPS_CMD_RCGR    (CLK_CTL_BASE + 0x5024)
+#define GCC_BLSP1_QUP4_SPI_CFG_RCGR         (CLK_CTL_BASE + 0x5028)
+#define GCC_BLSP1_QUP4_SPI_APPS_M           (CLK_CTL_BASE + 0x502C)
+#define GCC_BLSP1_QUP4_SPI_APPS_N           (CLK_CTL_BASE + 0x5030)
+#define GCC_BLSP1_QUP4_SPI_APPS_D           (CLK_CTL_BASE + 0x5034)
+
+#define GCC_BLSP1_QUP5_SPI_APPS_CBCR        (CLK_CTL_BASE + 0x601C)
+#define GCC_BLSP1_QUP5_SPI_APPS_CMD_RCGR    (CLK_CTL_BASE + 0x6024)
+#define GCC_BLSP1_QUP5_SPI_CFG_RCGR         (CLK_CTL_BASE + 0x6028)
+#define GCC_BLSP1_QUP5_SPI_APPS_M           (CLK_CTL_BASE + 0x602C)
+#define GCC_BLSP1_QUP5_SPI_APPS_N           (CLK_CTL_BASE + 0x6030)
+#define GCC_BLSP1_QUP5_SPI_APPS_D           (CLK_CTL_BASE + 0x6034)
+
 /* GPLL */
 #define GPLL0_STATUS                (CLK_CTL_BASE + 0x21024)
 #define GPLL0_MODE                  (CLK_CTL_BASE + 0x21000)
diff --git a/platform/msm8909/msm8909-clock.c b/platform/msm8909/msm8909-clock.c
index 04a7a42..433d18e 100644
--- a/platform/msm8909/msm8909-clock.c
+++ b/platform/msm8909/msm8909-clock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014,2018, 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
@@ -564,6 +564,99 @@
 	},
 };
 
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_spi_apps_clk[] = {
+	F( 960000,	cxo,	10,	1,	2),
+	F( 4800000,	cxo,	4,	0,	0),
+	F( 9600000,	cxo,	2,	0,	0),
+	F( 16000000,	gpll0,	10,	1,	5),
+	F( 19200000,	cxo,	1,	0,	0),
+	F( 25000000,	gpll0,	16,	1,	2),
+	F( 50000000,	gpll0,	16,	0,	0),
+	F_END
+};
+
+static struct rcg_clk gcc_blsp1_qup3_spi_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP3_SPI_CFG_RCGR,
+	.m_reg        = (uint32_t *) GCC_BLSP1_QUP3_SPI_APPS_M,
+	.n_reg        = (uint32_t *) GCC_BLSP1_QUP3_SPI_APPS_N,
+	.d_reg        = (uint32_t *) GCC_BLSP1_QUP3_SPI_APPS_D,
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_blsp1_qup1_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_spi_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+	.cbcr_reg = GCC_BLSP1_QUP3_SPI_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup3_spi_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct rcg_clk gcc_blsp1_qup4_spi_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP4_SPI_CFG_RCGR,
+	.m_reg        = (uint32_t *) GCC_BLSP1_QUP4_SPI_APPS_M,
+	.n_reg        = (uint32_t *) GCC_BLSP1_QUP4_SPI_APPS_N,
+	.d_reg        = (uint32_t *) GCC_BLSP1_QUP4_SPI_APPS_D,
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_blsp1_qup1_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_spi_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+	.cbcr_reg = GCC_BLSP1_QUP4_SPI_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup4_spi_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct rcg_clk gcc_blsp1_qup5_spi_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP5_SPI_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP5_SPI_CFG_RCGR,
+	.m_reg        = (uint32_t *) GCC_BLSP1_QUP5_SPI_APPS_M,
+	.n_reg        = (uint32_t *) GCC_BLSP1_QUP5_SPI_APPS_N,
+	.d_reg        = (uint32_t *) GCC_BLSP1_QUP5_SPI_APPS_D,
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_blsp1_qup1_spi_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup5_spi_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
+	.cbcr_reg = GCC_BLSP1_QUP5_SPI_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup5_spi_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 /* Display clocks */
 static struct clk_freq_tbl ftbl_mdss_esc0_1_clk[] = {
 	F_MM(19200000,    cxo,   1,   0,   0),
@@ -714,6 +807,13 @@
 	CLK_LOOKUP("gcc_blsp1_qup5_i2c_apps_clk", gcc_blsp1_qup5_i2c_apps_clk.c),
 	CLK_LOOKUP("gcc_blsp1_qup6_i2c_apps_clk_src", gcc_blsp1_qup5_i2c_apps_clk_src.c),
 	CLK_LOOKUP("gcc_blsp1_qup6_i2c_apps_clk", gcc_blsp1_qup5_i2c_apps_clk.c),
+	CLK_LOOKUP("blsp1_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup3_spi_apps_clk_src", gcc_blsp1_qup3_spi_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup3_spi_apps_clk", gcc_blsp1_qup3_spi_apps_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup4_spi_apps_clk_src", gcc_blsp1_qup4_spi_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup4_spi_apps_clk", gcc_blsp1_qup4_spi_apps_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup5_spi_apps_clk_src", gcc_blsp1_qup5_spi_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup5_spi_apps_clk", gcc_blsp1_qup5_spi_apps_clk.c),
 
 	CLK_LOOKUP("mdp_ahb_clk", mdp_ahb_clk.c),
 	CLK_LOOKUP("mdss_esc0_clk", mdss_esc0_clk.c),
diff --git a/platform/msm_shared/ab_partition_parser.c b/platform/msm_shared/ab_partition_parser.c
index a354316..7cee1a8 100644
--- a/platform/msm_shared/ab_partition_parser.c
+++ b/platform/msm_shared/ab_partition_parser.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 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:
@@ -358,14 +358,13 @@
 			return i;
 	}
 
-	/* NO Bootable slot */
-	panic("ERROR: Unable to find any bootable slot");
-	return 0;
+	dprintf(CRITICAL, "ERROR: Unable to find any bootable slot");
+	return INVALID;
 }
 
 int partition_find_boot_slot()
 {
-	int boot_slot;
+	int boot_slot, next_slot;
 	int slt_index;
 	uint64_t boot_retry_count;
 	struct partition_entry *partition_entries = partition_get_partition_entries();
@@ -393,8 +392,16 @@
 		/* Mark slot invalid and unbootable */
 		partition_deactivate_slot(boot_slot);
 
-		partition_switch_slots(boot_slot, next_active_bootable_slot(partition_entries));
-		reboot_device(0);
+		next_slot = next_active_bootable_slot(partition_entries);
+		if (next_slot != INVALID)
+		{
+			partition_switch_slots(boot_slot, next_slot);
+			reboot_device(0);
+		}
+		else
+		{
+			boot_slot = INVALID;
+		}
 	}
 	else
 	{
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
index 8733afa..cf4db48 100644
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2018 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
@@ -125,6 +125,15 @@
 		if (ret)
 			goto msm_display_config_out;
 		break;
+	case SPI_PANEL:
+		dprintf(INFO, "Config SPI PANEL.\n");
+		ret = mdss_spi_init();
+		if (ret)
+			goto msm_display_config_out;
+		ret = mdss_spi_panel_init(pinfo);
+		if (ret)
+			goto msm_display_config_out;
+		break;
 	case HDMI_PANEL:
 		dprintf(INFO, "Config HDMI PANEL.\n");
 		ret = mdss_hdmi_config(pinfo, &(panel->fb));
@@ -243,6 +252,12 @@
 		if (ret)
 			goto msm_display_on_out;
 		break;
+	case SPI_PANEL:
+		dprintf(INFO, "Turn on SPI_PANEL.\n");
+		ret = mdss_spi_on(pinfo, &(panel->fb));
+		if (ret)
+			goto msm_display_on_out;
+		break;
 #endif
 #ifdef DISPLAY_TYPE_QPIC
 	case QPIC_PANEL:
diff --git a/platform/msm_shared/include/mdp4.h b/platform/msm_shared/include/mdp4.h
index e463302..8bbb3a7 100644
--- a/platform/msm_shared/include/mdp4.h
+++ b/platform/msm_shared/include/mdp4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, 2018 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
@@ -124,4 +124,8 @@
 int mdss_hdmi_on(struct msm_panel_info *pinfo);
 int mdss_hdmi_off(struct msm_panel_info *pinfo);
 int mdss_hdmi_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+
+int mdss_spi_init(void);
+int mdss_spi_panel_init(struct msm_panel_info *pinfo);
+int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb);
 #endif
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index f458328..6ca84ac 100644
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -53,6 +53,7 @@
 #define LVDS_PANEL		11	/* LVDS */
 #define EDP_PANEL		12	/* EDP */
 #define QPIC_PANEL		13	/* QPIC */
+#define SPI_PANEL		14
 
 #define DISPLAY_UNKNOWN		0
 #define DISPLAY_1		1
@@ -92,6 +93,21 @@
 	uint32_t rev;
 };
 
+struct mdss_spi_cmd {
+	int size;
+	char *payload;
+	int wait;
+	uint8_t cmds_post_tg;
+};
+
+struct spi_panel_info {
+	int num_of_panel_cmds;
+	struct mdss_spi_cmd *panel_cmds;
+	uint8_t *signature_addr;
+	uint8_t *signature;
+	uint8_t *signature_len;
+};
+
 struct hdmi_panel_info {
 	uint32_t h_back_porch;
 	uint32_t h_front_porch;
@@ -411,6 +427,7 @@
 	struct lvds_panel_info lvds;
 	struct hdmi_panel_info hdmi;
 	struct edp_panel_info edp;
+	struct spi_panel_info spi;
 	struct dsi2HDMI_panel_info adv7533;
 	bool has_bridge_chip;
 
diff --git a/platform/msm_shared/include/qup.h b/platform/msm_shared/include/qup.h
new file mode 100755
index 0000000..5253b4c
--- /dev/null
+++ b/platform/msm_shared/include/qup.h
@@ -0,0 +1,146 @@
+/* Copyright (c) 2017-2018, 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, Inc. 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  __QUP__
+#define  __QUP__
+
+#include <stdint.h>
+
+#define MAX_READ_SPEED_HZ 9600000
+#define MAX_SPEED_HZ 50000000
+
+/* QUP_IO_MODES fields */
+#define QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN  0x00010000
+#define QUP_IO_MODES_PACK_EN              0x00008000
+#define QUP_IO_MODES_UNPACK_EN            0x00004000
+#define QUP_IO_MODES_INPUT_MODE           0x00003000
+#define QUP_IO_MODES_OUTPUT_MODE          0x00000C00
+#define QUP_IO_MODES_INPUT_FIFO_SIZE      0x00000380
+#define QUP_IO_MODES_INPUT_BLOCK_SIZE     0x00000060
+#define QUP_IO_MODES_OUTPUT_FIFO_SIZE     0x0000001C
+#define QUP_IO_MODES_OUTPUT_BLOCK_SIZE    0x00000003
+
+#define INPUT_BLOCK_SZ_SHIFT		5
+#define INPUT_FIFO_SZ_SHIFT			7
+#define OUTPUT_BLOCK_SZ_SHIFT		0
+#define OUTPUT_FIFO_SZ_SHIFT		2
+#define OUTPUT_MODE_SHIFT			10
+#define INPUT_MODE_SHIFT			12
+#define INPUT_MODE_MASK		(3 << INPUT_MODE_SHIFT)
+#define OUTPUT_MODE_MASK	(3 << OUTPUT_MODE_SHIFT)
+
+/* QUP_STATE fields */
+#define QUP_STATE_CLEAR_BITS		0x2
+
+/* QUP_ERROR_FLAGS fields */
+#define QUP_ERROR_OUTPUT_OVER_RUN	BIT(5)
+#define QUP_ERROR_INPUT_UNDER_RUN	BIT(4)
+#define QUP_ERROR_OUTPUT_UNDER_RUN	BIT(3)
+#define QUP_ERROR_INPUT_OVER_RUN	BIT(2)
+
+/* QUP_OPERATIONAL fields */
+#define QUP_OP_MAX_INPUT_DONE_FLAG	BIT(11)
+#define QUP_OP_MAX_OUTPUT_DONE_FLAG	BIT(10)
+#define QUP_OP_IN_SERVICE_FLAG		BIT(9)
+#define QUP_OP_OUT_SERVICE_FLAG		BIT(8)
+#define QUP_OP_IN_FIFO_FULL			BIT(7)
+#define QUP_OP_OUT_FIFO_FULL		BIT(6)
+#define QUP_OP_IN_FIFO_NOT_EMPTY	BIT(5)
+#define QUP_OP_OUT_FIFO_NOT_EMPTY	BIT(4)
+
+/* QUP_IO_MODES fields */
+#define QUP_IO_MODES_FIFO		0
+#define QUP_IO_MODES_BLOCK		1
+#define QUP_IO_MODES_DMOV		2
+#define QUP_IO_MODES_BAM		3
+
+/* QUP_CONFIG fields */
+#define QUP_CONFIG_SPI_MODE			(1 << 8)
+#define QUP_CONFIG_CLOCK_AUTO_GATE	BIT(13)
+#define QUP_CONFIG_NO_INPUT			BIT(7)
+#define QUP_CONFIG_NO_OUTPUT		BIT(6)
+#define QUP_CONFIG_N				0x001f
+
+/* QUP_MX_OUTPUT_CNT only supports
+ * 0:15 bits as Number of writes of
+ * size N to the mini-core per RUN state.
+ * And make the count be multiple of max bytes per word.
+ */
+#define MAX_QUP_MX_OUTPUT_COUNT 0xFFF8
+#define MAX_QUP_MX_TRANSFER_COUNT 0xFFF8
+
+/* QUP Registers */
+enum {
+	QUP_CONFIG = 0x0,
+	QUP_STATE = 0x4,
+	QUP_IO_MODES = 0x8,
+	QUP_SW_RESET = 0xC,
+	QUP_OPERATIONAL = 0x18,
+	QUP_ERROR_FLAGS = 0x1C,
+	QUP_ERROR_FLAGS_EN = 0x20,
+	QUP_TEST_CTRL = 0x24,
+	QUP_OPERATIONAL_MASK = 0x28,
+	QUP_HW_VERSION = 0x30,
+	QUP_MX_READ_CNT = 0x208,
+	QUP_MX_INPUT_CNT = 0x200,
+	QUP_MX_INPUT_CNT_CURRENT = 0x204,
+	QUP_MX_OUTPUT_CNT = 0x100,
+	QUP_MX_OUTPUT_CNT_CURRENT = 0x104,
+	QUP_OUTPUT_DEBUG = 0x108,
+	QUP_OUTPUT_FIFO_WORD_CNT = 0x10C,
+	QUP_OUTPUT_FIFO_BASE = 0x110,
+	QUP_MX_WRITE_CNT = 0x150,
+	QUP_MX_WRITE_CNT_CURRENT = 0x154,
+	QUP_INPUT_READ_CUR = 0x20C,
+	QUP_INPUT_DEBUG = 0x210,
+	QUP_INPUT_FIFO_CNT = 0x214,
+	QUP_INPUT_FIFO_BASE = 0x218,
+	QUP_I2C_CLK_CTL = 0x400,
+	QUP_I2C_STATUS = 0x404,
+};
+
+/* QUP States and reset values */
+enum qup_state{
+	QUP_RESET_STATE = 0,
+	QUP_RUN_STATE = 1U,
+	QUP_STATE_MASK = 3U,
+	QUP_PAUSE_STATE = 3U,
+	QUP_STATE_VALID = 1U << 2,
+	QUP_I2C_MAST_GEN = 1U << 4,
+	QUP_OPERATIONAL_RESET = 0xFF0,
+	QUP_I2C_STATUS_RESET = 0xFFFFFC,
+};
+
+/* QUP OPERATIONAL FLAGS */
+enum {
+	QUP_OUT_SVC_FLAG = 1U << 8,
+	QUP_IN_SVC_FLAG = 1U << 9,
+	QUP_MX_INPUT_DONE = 1U << 11,
+};
+
+#endif				/* __QUP__ */
diff --git a/platform/msm_shared/include/spi_qup.h b/platform/msm_shared/include/spi_qup.h
new file mode 100755
index 0000000..b91ab5c
--- /dev/null
+++ b/platform/msm_shared/include/spi_qup.h
@@ -0,0 +1,120 @@
+/* Copyright (c) 2017-2018, 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, Inc. 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  __SPI_QUP__
+#define  __SPI_QUP__
+
+#include <stdint.h>
+#include <qup.h>
+
+/* SPI_ERROR_FLAGS and SPI_ERROR_FLAGS_EN fields */
+#define SPI_ERROR_CLK_OVER_RUN		BIT(1)
+#define SPI_ERROR_CLK_UNDER_RUN		BIT(0)
+
+#define SPI_CONFIG                    0x0300
+#define SPI_IO_CONTROL                0x0304
+#define SPI_IO_MODES                  0x0008
+#define SPI_SW_RESET                  0x000C
+#define SPI_TIME_OUT_CURRENT          0x0014
+#define SPI_MX_OUTPUT_COUNT           0x0100
+#define SPI_MX_OUTPUT_CNT_CURRENT     0x0104
+#define SPI_MX_INPUT_COUNT            0x0200
+#define SPI_MX_INPUT_CNT_CURRENT      0x0204
+#define SPI_MX_READ_COUNT             0x0208
+#define SPI_MX_READ_CNT_CURRENT       0x020C
+#define SPI_OPERATIONAL               0x0018
+#define SPI_ERROR_FLAGS               0x001C
+#define SPI_ERROR_FLAGS_EN            0x0020
+#define SPI_DEASSERT_WAIT             0x0310
+#define SPI_OUTPUT_DEBUG              0x0108
+#define SPI_INPUT_DEBUG               0x0210
+#define SPI_TEST_CTRL                 0x0024
+#define SPI_OUTPUT_FIFO               0x0110
+#define SPI_INPUT_FIFO                0x0218
+#define SPI_STATE                     0x0004
+
+#define SPI_IO_C_NO_TRI_STATE		BIT(0)
+#define SPI_IO_C_CLK_ALWAYS_ON		BIT(9)
+#define SPI_IO_C_MX_CS_MODE			BIT(8)
+#define SPI_IO_C_CS0_ACTIVE_HIGH	BIT(4)
+#define SPI_IO_C_CS_SELECT_CS0		00 << 2
+#define SPI_IO_C_CLK_IDLE_HIGH		BIT(10)
+#define SPI_IO_C_FORCE_CS              BIT(11)
+
+/* SPI_CONFIG fields */
+#define SPI_CONFIG_HS_MODE			BIT(10)
+#define SPI_CONFIG_INPUT_FIRST		BIT(9)
+#define SPI_CONFIG_LOOPBACK			BIT(8)
+
+#define DEFAULT_BYTES_PER_WORD	0x2
+
+#define BITS_PER_BYTE 	8
+
+#define EIO         5
+#define ENOMEM      12
+#define EBUSY       16
+#define ENODEV      19
+#define ENOSYS      38
+#define EPROTONOSUPPORT 93
+#define ETIMEDOUT   110
+
+struct spi_transfer {
+	const unsigned char	*tx_buf;
+	int	len;
+	unsigned char *rx_buf;
+	unsigned int speed_hz;
+};
+
+/**
+ * qup_spi_dev - spi device config structure
+ * @ qup_base - base register address of QUP.
+ * @ qup_irq - irq number of QUP.
+ * @ tx_bytes - current transfered output data length in bytes
+ * @ bytes_per_word - bytes number per word write to FIFO, valid range [1-4]
+ * @ xfer - pointer to SPI transfer contents structure.
+ */
+struct qup_spi_dev {
+	unsigned int qup_base;
+	int qup_irq;
+	int tx_bytes;
+	int rx_bytes;
+	unsigned int bytes_per_word;
+	unsigned int bit_shift_en;
+	unsigned int unpack_en;
+	struct spi_transfer *xfer;
+	unsigned int max_speed_hz;
+	uint8_t blsp_id;
+	uint8_t qup_id;
+};
+
+/* Function Definitions */
+struct qup_spi_dev *qup_blsp_spi_init(uint8_t blsp_id, uint8_t qup_id);
+int qup_spi_deinit(struct qup_spi_dev *dev);
+int spi_qup_transfer(struct qup_spi_dev *dev, const unsigned char * tx_buf, unsigned int data_size);
+
+#endif				/* __SPI_QUP__ */
diff --git a/platform/msm_shared/include/splash.h b/platform/msm_shared/include/splash.h
index badb8d0..59147a0 100644
--- a/platform/msm_shared/include/splash.h
+++ b/platform/msm_shared/include/splash.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010,2014, 2018 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
@@ -30,9 +30,8 @@
 #ifndef __PLATFORM_SPLASH_H
 #define __PLATFORM_SPLASH_H
 
-#if (!DISPLAY_TYPE_MIPI)
-#define SPLASH_IMAGE_WIDTH     124
-#define SPLASH_IMAGE_HEIGHT    113
+#define SPLASH_IMAGE_WIDTH     113
+#define SPLASH_IMAGE_HEIGHT    124
 /* This image is (SPLASH_IMAGE_WIDTH x SPLASH_IMAGE_WIDTH) raw image */
 static char imageBuffer[] = {
 
@@ -3542,11 +3541,6 @@
 
 };
 
-#else
-
-#define SPLASH_IMAGE_WIDTH     113
-#define SPLASH_IMAGE_HEIGHT    124
-
 /* This image is 228x113 raw Image resembling QuIC logo*/
 
 static char imageBuffer_rgb888[] = {
@@ -15252,6 +15246,5 @@
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 #endif
-#endif
 
 #endif
diff --git a/platform/msm_shared/mdss_spi.c b/platform/msm_shared/mdss_spi.c
new file mode 100644
index 0000000..4819478
--- /dev/null
+++ b/platform/msm_shared/mdss_spi.c
@@ -0,0 +1,173 @@
+/* Copyright (c) 2017-2018 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 <spi_qup.h>
+#include <msm_panel.h>
+#include <target/display.h>
+#include <platform/gpio.h>
+
+#define SUCCESS		0
+#define FAIL		1
+
+static struct qup_spi_dev *dev = NULL;
+
+static int mdss_spi_write_cmd(const char *buf)
+{
+	int ret = 0;
+
+	if (!dev) {
+		dprintf(CRITICAL, "SPI has not been initialized\n");
+		return -ENODEV;
+	}
+
+	dev->bytes_per_word = 1;
+	dev->bit_shift_en = 1;
+
+	gpio_set(spi_dc_gpio.pin_id, 0);
+	ret = spi_qup_transfer(dev, buf, 1);
+	gpio_set(spi_dc_gpio.pin_id, 2);
+	if (ret)
+		dprintf(CRITICAL, "Send SPI command to panel failed\n");
+
+	return ret;
+}
+
+static int mdss_spi_write_data(const char *buf, size_t len)
+{
+	int ret = 0;
+
+	if (!dev) {
+		dprintf(CRITICAL, "SPI has not been initialized\n");
+		return -ENODEV;
+	}
+
+	dev->bytes_per_word = 1;
+	dev->bit_shift_en = 1;
+
+	gpio_set(spi_dc_gpio.pin_id, 2);
+	ret = spi_qup_transfer(dev, buf, len);
+	if (ret)
+		dprintf(CRITICAL, "Send SPI parameters to panel failed\n");
+
+	return ret;
+}
+
+static int mdss_spi_write_frame(const char *buf, size_t len)
+{
+	int ret = 0;
+
+	if (!dev) {
+		dprintf(CRITICAL, "SPI has not been initialized\n");
+		return -ENODEV;
+	}
+
+	dev->bytes_per_word = 2;
+	dev->bit_shift_en = 1;
+	dev->unpack_en = 0;
+
+	gpio_set(spi_dc_gpio.pin_id, 2);
+	ret = spi_qup_transfer(dev, buf, len);
+
+	return ret;
+}
+
+static void spi_read_panel_data(unsigned char *buf,  int len)
+{
+	int ret = 0;
+
+	if (!dev) {
+		 dprintf(CRITICAL, "SPI has not been initialized\n");
+		 return -ENODEV;
+	}
+	dev->bytes_per_word = 1;
+	dev->bit_shift_en = 1;
+
+	gpio_set(spi_dc_gpio.pin_id, 0);
+	ret = spi_qup_transfer(dev, buf, len);
+	gpio_set(spi_dc_gpio.pin_id, 2);
+
+	if (ret)
+		dprintf(CRITICAL, "Send SPI command to panel failed\n");
+
+	return;
+}
+
+int mdss_spi_init(void)
+{
+	if (!dev) {
+		dev = qup_blsp_spi_init(SPI_BLSP_ID, SPI_QUP_ID);
+		if (!dev) {
+			dprintf(CRITICAL, "Failed initializing SPI\n");
+			return -ENODEV;
+		}
+	}
+
+	gpio_tlmm_config(spi_dc_gpio.pin_id, 0, spi_dc_gpio.pin_direction,
+			spi_dc_gpio.pin_pull, spi_dc_gpio.pin_strength,
+			spi_dc_gpio.pin_state);
+	return SUCCESS;
+}
+
+int mdss_spi_panel_init(struct msm_panel_info *pinfo)
+{
+	int cmd_count = 0;
+	int ret = 0;
+
+	while (cmd_count < pinfo->spi.num_of_panel_cmds) {
+		if (pinfo->spi.panel_cmds[cmd_count].cmds_post_tg){
+			cmd_count ++;
+			continue;
+		}
+
+		mdss_spi_write_cmd(pinfo->spi.panel_cmds[cmd_count].payload);
+		if (pinfo->spi.panel_cmds[cmd_count].size > 1)
+			mdss_spi_write_data(
+				pinfo->spi.panel_cmds[cmd_count].payload + 1,
+				pinfo->spi.panel_cmds[cmd_count].size - 1);
+
+		if (pinfo->spi.panel_cmds[cmd_count].wait)
+			mdelay(pinfo->spi.panel_cmds[cmd_count].wait);
+
+		cmd_count ++;
+	}
+	return SUCCESS;
+}
+
+int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+	int buf_size = 0;
+	int ret = 0;
+
+	buf_size =  fb->width * fb->height * (fb->bpp / 8);
+	ret = mdss_spi_write_frame(fb->base, buf_size);
+	if (ret)
+		dprintf(CRITICAL, "Send SPI frame data to panel failed\n");
+
+	return ret;
+}
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index bac3f47..f8460ff 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -524,13 +524,15 @@
 			$(LOCAL_DIR)/certificate.o \
 			$(LOCAL_DIR)/image_verify.o \
 			$(LOCAL_DIR)/i2c_qup.o \
-			$(LOCAL_DIR)/qseecom_lk.o \
+			$(LOCAL_DIR)/spi_qup.o \
+            $(LOCAL_DIR)/qseecom_lk.o \
 			$(LOCAL_DIR)/mdp3.o \
 			$(LOCAL_DIR)/display.o \
 			$(LOCAL_DIR)/mipi_dsi.o \
 			$(LOCAL_DIR)/mipi_dsi_phy.o \
 			$(LOCAL_DIR)/flash-ubi.o \
-			$(LOCAL_DIR)/mipi_dsi_autopll.o
+			$(LOCAL_DIR)/mipi_dsi_autopll.o\
+			$(LOCAL_DIR)/mdss_spi.o
 endif
 
 ifeq ($(PLATFORM),mdm9607)
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index fa5c420..c8a3e48 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -519,6 +519,7 @@
 	HW_PLATFORM_SUBTYPE_8909_PM660 = 15,
 	HW_PLATFORM_SUBTYPE_8909_COMPAL_ALPHA = 19,
 	HW_PLATFORM_SUBTYPE_8909_PM660_V1 = 18,
+	HW_PLATFORM_SUBTYPE_INTRINSIC_SOM = 20,
 	HW_PLATFORM_SUBTYPE_32BITS = 0x7FFFFFFF
 };
 
diff --git a/platform/msm_shared/spi_qup.c b/platform/msm_shared/spi_qup.c
new file mode 100755
index 0000000..c43aabc
--- /dev/null
+++ b/platform/msm_shared/spi_qup.c
@@ -0,0 +1,449 @@
+/* Copyright (c) 2017-2018, 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, Inc. 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.
+ */
+
+/*
+ * QUP spi driver for Qualcomm MSM platforms
+ *
+ */
+
+#include <debug.h>
+#include <arch/arm.h>
+#include <reg.h>
+#include <kernel/thread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gsbi.h>
+#include <spi_qup.h>
+#include <platform/irqs.h>
+#include <platform/iomap.h>
+#include <platform/gpio.h>
+#include <platform/clock.h>
+#include <platform/timer.h>
+#include <platform/interrupts.h>
+
+//#define DEBUGLEVEL 3
+
+static unsigned int spi_get_qup_hw_ver(struct qup_spi_dev *dev)
+{
+	unsigned int data = readl_relaxed(dev->qup_base + QUP_HW_VERSION);
+
+	dprintf(SPEW, "Qup hardware version is 0x%x\n", data);
+	return data;
+}
+
+static void qup_print_status(struct qup_spi_dev *dev)
+{
+	unsigned val;
+	val = readl(dev->qup_base + QUP_CONFIG);
+	dprintf(SPEW, "Qup config is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_STATE);
+	dprintf(SPEW, "Qup state is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_IO_MODES);
+	dprintf(SPEW, "Qup mode is :0x%x\n", val);
+	val = readl(dev->qup_base + SPI_IO_CONTROL);
+	dprintf(SPEW, "SPI_IO_CONTROL is :0x%x\n", val);
+	val = readl(dev->qup_base + SPI_CONFIG);
+	dprintf(SPEW, "SPI_CONFIG is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_MX_WRITE_CNT_CURRENT);
+	dprintf(SPEW, "QUP_MX_WRITE_CNT_CURRENT is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_MX_WRITE_CNT);
+	dprintf(SPEW, "QUP_MX_WRITE_CNT is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_MX_OUTPUT_CNT_CURRENT);
+	dprintf(SPEW, "QUP_MX_OUTPUT_CNT_CURRENT is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_MX_OUTPUT_CNT);
+	dprintf(SPEW, "QUP_MX_OUTPUT_CNT is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_OPERATIONAL);
+	dprintf(SPEW, "QUP_OPERATIONAL is :0x%x\n", val);
+	val = readl(dev->qup_base + QUP_OUTPUT_FIFO_WORD_CNT);
+	dprintf(SPEW, "QUP_OUTPUT_FIFO_WORD_CNT is :0x%x\n", val);
+}
+
+static inline bool qup_state_is_valid(struct qup_spi_dev *dev)
+{
+	unsigned int st = readl_relaxed(dev->qup_base + QUP_STATE);
+
+	return st & QUP_STATE_VALID;
+}
+
+static inline int qup_wait_state_valid(struct qup_spi_dev *dev)
+{
+	unsigned retries = 0xFFFF;
+
+	while (!qup_state_is_valid(dev) && (--retries != 0));
+
+	if(!retries)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int qup_poll_state(struct qup_spi_dev *dev, unsigned state)
+{
+	int ret = 0;
+	unsigned int status;
+
+	ret = qup_wait_state_valid(dev);
+
+	if(ret)
+		goto exit;
+
+	status = readl(dev->qup_base + QUP_STATE);
+	if ((status & (QUP_STATE_VALID | state)) ==
+		(QUP_STATE_VALID | state))
+			return 0;
+
+exit:
+	dprintf(SPEW, "Polling fail for state:0x%x\n", state);
+	qup_print_status(dev);
+	return ret;
+}
+
+static inline int qup_set_state(struct qup_spi_dev *dev,
+				    enum qup_state state)
+{
+	enum qup_state cur_state;
+
+	if (qup_wait_state_valid(dev)) {
+		qup_print_status(dev);
+		return -EIO;
+	}
+
+	cur_state = readl_relaxed(dev->qup_base + QUP_STATE);
+
+	/* For PAUSE_STATE to RESET_STATE,
+	 * two writes of (0b10) are required.
+	 */
+	if (((cur_state & QUP_STATE_MASK) == QUP_PAUSE_STATE) &&
+			(state == QUP_RESET_STATE)) {
+		writel(QUP_STATE_CLEAR_BITS, dev->qup_base + QUP_STATE);
+		writel(QUP_STATE_CLEAR_BITS, dev->qup_base + QUP_STATE);
+	} else {
+		writel((cur_state & ~QUP_STATE_MASK) | state,
+		       dev->qup_base + QUP_STATE);
+	}
+
+	if (qup_poll_state(dev, state)) {
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static inline void qup_register_init(struct qup_spi_dev *dev)
+{
+	/* Initialize QUP registers */
+	qup_set_state(dev, QUP_RESET_STATE);
+	writel(0x00000001, dev->qup_base + QUP_SW_RESET);
+	qup_wait_state_valid(dev);
+	qup_set_state(dev, QUP_RESET_STATE);
+
+	writel(0x00000000, dev->qup_base + QUP_CONFIG);
+	writel(0x00000000, dev->qup_base + QUP_IO_MODES);
+	writel(0xfff0, dev->qup_base + QUP_OPERATIONAL);
+	writel(0x7e, dev->qup_base + QUP_ERROR_FLAGS);
+	writel(0x00000000, dev->qup_base + QUP_TEST_CTRL);
+	writel(0x00000000, dev->qup_base + QUP_OPERATIONAL_MASK);
+	writel(0x0, dev->qup_base + QUP_MX_INPUT_CNT);
+	writel(0x1, dev->qup_base + QUP_MX_OUTPUT_CNT);
+	writel(0x0, dev->qup_base + QUP_MX_READ_CNT);
+}
+
+static inline void spi_register_init(struct qup_spi_dev *dev)
+{
+	/* Set SPI mini core to QUP config */
+	writel(QUP_CONFIG_SPI_MODE | QUP_CONFIG_NO_INPUT, dev->qup_base + QUP_CONFIG);
+
+	/* Initialize SPI mini core registers */
+	writel(0, dev->qup_base + SPI_CONFIG);
+	writel(SPI_IO_C_NO_TRI_STATE | SPI_IO_C_CS_SELECT_CS0 | SPI_IO_C_CLK_IDLE_HIGH,
+		dev->qup_base + SPI_IO_CONTROL);
+	writel(SPI_ERROR_CLK_OVER_RUN | SPI_ERROR_CLK_UNDER_RUN, dev->qup_base + SPI_ERROR_FLAGS_EN);
+	writel(0, dev->qup_base + SPI_DEASSERT_WAIT);
+
+	qup_print_status(dev);
+}
+
+static void spi_qup_io_config_block(struct qup_spi_dev *dev, int len)
+{
+	unsigned int config, iomode, mode;
+	unsigned int bits_per_word;
+
+	qup_register_init(dev);
+	spi_register_init(dev);
+
+	/* bytes_per_word valid range is [1-4].
+	 * Other value may not working as expected.
+	 */
+	dev->bytes_per_word = dev->bytes_per_word % 5;
+
+	/* If bytes_per_word not given, use DEFAULT_BYTES_PER_WORD.
+	 */
+	if(!dev->bytes_per_word)
+		dev->bytes_per_word = DEFAULT_BYTES_PER_WORD;
+
+	bits_per_word = dev->bytes_per_word * 8 - 1;
+
+	writel(len / dev->bytes_per_word, dev->qup_base + QUP_MX_OUTPUT_CNT);
+	writel(0, dev->qup_base + QUP_MX_INPUT_CNT);
+	writel(0, dev->qup_base + QUP_MX_READ_CNT);
+	writel(0, dev->qup_base + QUP_MX_WRITE_CNT);
+
+	mode = QUP_IO_MODES_BLOCK;
+	iomode = readl_relaxed(dev->qup_base + QUP_IO_MODES);
+	iomode &= ~(INPUT_MODE_MASK | OUTPUT_MODE_MASK);
+	if(dev->unpack_en)
+		iomode |= QUP_IO_MODES_UNPACK_EN;
+	else
+		iomode &= ~QUP_IO_MODES_UNPACK_EN;
+	iomode |= (mode << OUTPUT_MODE_SHIFT);
+	iomode |= (mode << INPUT_MODE_SHIFT);
+	if(dev->bit_shift_en)
+		iomode |= QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN;
+	else
+		iomode &= ~QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN;
+	writel(iomode, dev->qup_base + QUP_IO_MODES);
+
+	config = readl_relaxed(dev->qup_base + QUP_CONFIG);
+	config |= QUP_CONFIG_NO_INPUT;
+	config |= QUP_CONFIG_SPI_MODE;
+	config |= bits_per_word;
+	writel(config, dev->qup_base + QUP_CONFIG);
+
+	writel(0, dev->qup_base + QUP_OPERATIONAL_MASK);
+
+	unmask_interrupt(dev->qup_irq);
+}
+
+static void spi_qup_fifo_write(struct qup_spi_dev *dev, struct spi_transfer *xfer)
+{
+	const unsigned char *tx_buf = xfer->tx_buf;
+	unsigned int word, state, data;
+	unsigned int idx;
+
+	while (dev->tx_bytes < xfer->len) {
+
+		state = readl_relaxed(dev->qup_base + QUP_OPERATIONAL);
+		if (state & QUP_OP_OUT_FIFO_FULL)
+		{
+			dprintf(SPEW, "%s: oper QUP_OP_OUT_FIFO_FULL: 0x%x"
+				"dev->tx_bytes:0x%x, xfer->len:0x%x\n",
+				__func__, state, dev->tx_bytes, xfer->len);
+			break;
+		}
+
+		word = 0;
+		for (idx = 0; idx < dev->bytes_per_word; idx++, dev->tx_bytes++) {
+
+			if (!tx_buf) {
+				dprintf(CRITICAL, "%s: tx_buf null error.\n", __func__);
+				dev->tx_bytes += dev->bytes_per_word;
+				break;
+			}
+			data = dev->tx_bytes < xfer->len ? tx_buf[dev->tx_bytes] : 0;
+			word |= data << (BITS_PER_BYTE * idx);
+		}
+
+		writel(word, dev->qup_base + QUP_OUTPUT_FIFO_BASE);
+	}
+}
+
+int _spi_qup_transfer(struct qup_spi_dev *dev, struct spi_transfer *xfer)
+{
+	int ret = -EIO;
+	int retries = 0xFF;
+	unsigned val;
+
+	dev->xfer     = xfer;
+	dev->tx_bytes = 0;
+
+	spi_qup_io_config_block(dev, xfer->len);
+
+	ret = qup_set_state(dev, QUP_RUN_STATE);
+	if (ret) {
+		dprintf(CRITICAL, "%s: cannot set first RUN state\n", __func__);
+		goto exit;
+	}
+
+	while((readl(dev->qup_base + QUP_MX_OUTPUT_CNT)
+		!= readl(dev->qup_base + QUP_MX_OUTPUT_CNT_CURRENT))
+		&& retries--);
+
+	while(readl(dev->qup_base + QUP_MX_OUTPUT_CNT_CURRENT) ) {
+		val = readl(dev->qup_base + QUP_OPERATIONAL);
+		val &= ~QUP_OP_OUT_SERVICE_FLAG;
+		writel(val, dev->qup_base + QUP_OPERATIONAL);
+
+		ret = qup_set_state(dev, QUP_PAUSE_STATE);
+		if (ret) {
+			dprintf(CRITICAL, "%s: cannot set PAUSE state\n", __func__);
+			goto exit;
+		}
+
+		spi_qup_fifo_write(dev, xfer);
+
+		ret = qup_set_state(dev, QUP_RUN_STATE);
+		if (ret) {
+			dprintf(CRITICAL, "%s: cannot set RUN state\n", __func__);
+			goto exit;
+		}
+	}
+	dprintf(SPEW, "dev->tx_bytes:0x%x, xfer->len:0x%x\n",
+		dev->tx_bytes, xfer->len);
+
+exit:
+	qup_set_state(dev, QUP_RESET_STATE);
+	dev->xfer = NULL;
+	return ret;
+}
+
+/**
+ * @brief Transfer data_size bytes data from tx_buf via spi
+ * @param dev		SPI config structure initialized from qup_blsp_spi_init
+ * @param tx_buf	output buffer pointer
+ * @param data_size	Should be multiple of max bytes per word
+ */
+int spi_qup_transfer(struct qup_spi_dev *dev, const unsigned char * tx_buf, unsigned int data_size)
+{
+	unsigned int cur = 0;
+	struct spi_transfer s_xfer;
+	int ret = -EIO;
+
+	if(!tx_buf)
+		return ret;
+
+	while(data_size > MAX_QUP_MX_OUTPUT_COUNT + cur) {
+		s_xfer.len = MAX_QUP_MX_OUTPUT_COUNT;
+		s_xfer.tx_buf = tx_buf + cur;
+
+		ret = _spi_qup_transfer(dev, &s_xfer);
+		if (ret)
+			goto exit;
+
+		cur += MAX_QUP_MX_OUTPUT_COUNT;
+	}
+
+	s_xfer.len = data_size - cur;
+	s_xfer.tx_buf = tx_buf + cur;
+	ret = _spi_qup_transfer(dev, &s_xfer);
+	if (ret)
+			goto exit;
+	return ret;
+
+exit:
+	dprintf(CRITICAL, "%s: transfer error!\n", __func__);
+	return ret;
+}
+
+static enum handler_return qup_spi_interrupt(void *arg)
+{
+	struct qup_spi_dev *dev = (struct qup_spi_dev *)arg;
+	unsigned int opflags, qup_err, spi_err;
+
+	if (!dev) {
+		dprintf(CRITICAL,
+			"dev_addr is NULL, that means spi_qup_init failed...\n");
+		return INT_NO_RESCHEDULE;
+	}
+
+	qup_err = readl_relaxed(dev->qup_base + QUP_ERROR_FLAGS);
+	spi_err = readl_relaxed(dev->qup_base + SPI_ERROR_FLAGS);
+	opflags = readl_relaxed(dev->qup_base + QUP_OPERATIONAL);
+
+	/* Writing a 'one' to the error bit to clear it. */
+	writel(qup_err, dev->qup_base + QUP_ERROR_FLAGS);
+	writel(spi_err, dev->qup_base + SPI_ERROR_FLAGS);
+	writel(opflags, dev->qup_base + QUP_OPERATIONAL);
+
+	if (qup_err) {
+		if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN)
+			dprintf(SPEW, "OUTPUT_OVER_RUN\n");
+		if (qup_err & QUP_ERROR_INPUT_UNDER_RUN)
+			dprintf(SPEW, "INPUT_UNDER_RUN\n");
+		if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN)
+			dprintf(SPEW, "OUTPUT_UNDER_RUN\n");
+		if (qup_err & QUP_ERROR_INPUT_OVER_RUN)
+			dprintf(SPEW, "INPUT_OVER_RUN\n");
+	}
+
+	if (spi_err) {
+		if (spi_err & SPI_ERROR_CLK_OVER_RUN)
+			dprintf(SPEW, "CLK_OVER_RUN\n");
+		if (spi_err & SPI_ERROR_CLK_UNDER_RUN)
+			dprintf(SPEW, "CLK_UNDER_RUN\n");
+	}
+
+	return INT_NO_RESCHEDULE;
+}
+
+static void qup_spi_sec_init(struct qup_spi_dev *dev)
+{
+	/* Get qup hw version */
+	spi_get_qup_hw_ver(dev);
+
+	qup_register_init(dev);
+	spi_register_init(dev);
+
+	/* Register the GSBIn QUP IRQ */
+	register_int_handler(dev->qup_irq, qup_spi_interrupt, dev);
+
+	/* Then disable it */
+	mask_interrupt(dev->qup_irq);
+}
+
+struct qup_spi_dev *qup_blsp_spi_init(uint8_t blsp_id, uint8_t qup_id)
+{
+	struct qup_spi_dev *dev;
+
+	dev = malloc(sizeof(struct qup_spi_dev));
+	if (!dev) {
+		return NULL;
+	}
+	dev = memset(dev, 0, sizeof(struct qup_spi_dev));
+
+	/* Platform uses BLSP */
+	dev->qup_irq = BLSP_QUP_IRQ(blsp_id, qup_id);
+	dev->qup_base = BLSP_QUP_BASE(blsp_id, qup_id);
+
+	/* Initialize the GPIO for BLSP spi */
+	gpio_config_blsp_spi(blsp_id, qup_id);
+
+	clock_config_blsp_spi(blsp_id, qup_id);
+
+	qup_spi_sec_init(dev);
+
+	return dev;
+}
+
+int qup_spi_deinit(struct qup_spi_dev *dev)
+{
+	/* Disable the qup_irq */
+	mask_interrupt(dev->qup_irq);
+	/* Free the memory used for dev */
+	free(dev);
+	return 0;
+}
diff --git a/project/msm8953.mk b/project/msm8953.mk
index a7a5f72..f14a49b 100644
--- a/project/msm8953.mk
+++ b/project/msm8953.mk
@@ -29,7 +29,7 @@
 endif
 
 ENABLE_SMD_SUPPORT := 1
-#ENABLE_PWM_SUPPORT := true
+ENABLE_PWM_SUPPORT := true
 
 #DEFINES += WITH_DEBUG_DCC=1
 DEFINES += WITH_DEBUG_LOG_BUF=1
diff --git a/target/msm8909/include/target/display.h b/target/msm8909/include/target/display.h
index 0e3a1bc..b778cf2 100644
--- a/target/msm8909/include/target/display.h
+++ b/target/msm8909/include/target/display.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2018 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
@@ -49,6 +49,10 @@
   "msmgpio", 37, 3, 1, 0, 1
 };
 
+static struct gpio_pin spi_bkl_gpio = {
+	"msmgpio", 60, 3, 1, 0, 1
+};
+
 static struct gpio_pin enp_gpio = {
   "msmgpio", 97, 3, 1, 0, 1
 };
@@ -57,6 +61,14 @@
   "msmgpio", 32, 3, 1, 0, 1
 };
 
+static struct gpio_pin dc_gpio = {
+	"msmgpio", 52, 3, 1, 0, 1
+};
+
+static struct gpio_pin spi_dc_gpio = {
+        "msmgpio", 59, 3, 1, 0, 1
+};
+
 static struct gpio_pin te_gpio = {
   0, 0, 0, 0, 0, 0
 };
@@ -108,4 +120,7 @@
 #define MIPI_VSYNC_BACK_PORCH_LINES  3
 #define MIPI_VSYNC_FRONT_PORCH_LINES 9
 
+#define SPI_BLSP_ID                  1
+#define SPI_QUP_ID                   3
+
 #endif
diff --git a/target/msm8909/oem_panel.c b/target/msm8909/oem_panel.c
index add0d9e..064539c 100644
--- a/target/msm8909/oem_panel.c
+++ b/target/msm8909/oem_panel.c
@@ -49,6 +49,7 @@
 #include "include/panel_auo_cx_qvga_cmd.h"
 #include "include/panel_auo_400p_cmd.h"
 #include "include/panel_auo_390p_cmd.h"
+#include "include/panel_st7789v2_qvga_spi_cmd.h"
 
 #define DISPLAY_MAX_PANEL_DETECTION 0
 #define ILI9806E_FWVGA_VIDEO_PANEL_POST_INIT_DELAY 68
@@ -78,6 +79,7 @@
 	AUO_CX_QVGA_CMD_PANEL,
 	AUO_400P_CMD_PANEL,
 	AUO_390P_CMD_PANEL,
+	ST7789v2_QVGA_SPI_CMD_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -98,6 +100,7 @@
 	{"auo_cx_qvga_cmd", AUO_CX_QVGA_CMD_PANEL},
 	{"auo_400p_cmd", AUO_400P_CMD_PANEL},
 	{"auo_390p_cmd", AUO_390P_CMD_PANEL},
+	{"ST7789V2_qvga_cmd", ST7789v2_QVGA_SPI_CMD_PANEL},
 };
 
 static uint32_t panel_id;
@@ -429,6 +432,19 @@
 					= AUO_390P_CMD_OFF_COMMAND;
 		memcpy(phy_db->timing, auo_390p_cmd_timings, TIMING_SIZE);
 		break;
+	case ST7789v2_QVGA_SPI_CMD_PANEL:
+		panelstruct->paneldata		= &st7789v2_qvga_cmd_panel_data;
+		panelstruct->panelres		= &st7789v2_qvga_cmd_panel_res;
+		panelstruct->color			= &st7789v2_qvga_cmd_color;
+		panelstruct->panelresetseq	= &st7789v2_qvga_cmd_reset_seq;
+		panelstruct->backlightinfo	= &st7789v2_qvga_cmd_backlight;
+		pinfo->spi.panel_cmds		= st7789v2_qvga_cmd_on_command;
+		pinfo->spi.num_of_panel_cmds= ST7789v2_QVGA_CMD_ON_COMMAND;
+		pinfo->spi.signature_addr	= &st7789v2_signature_addr;
+		pinfo->spi.signature		= st7789v2_signature;
+		pinfo->spi.signature_len	= st7789v2_signature_len;
+		pan_type = PANEL_TYPE_SPI;
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
diff --git a/target/msm8909/target_display.c b/target/msm8909/target_display.c
index e449cf0..a3d5848 100644
--- a/target/msm8909/target_display.c
+++ b/target/msm8909/target_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017-2018, 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
@@ -240,6 +240,15 @@
 			bkl_gpio.pin_direction, bkl_gpio.pin_pull,
 			bkl_gpio.pin_strength, bkl_gpio.pin_state);
 			gpio_set(bkl_gpio.pin_id, 2);
+
+		if (HW_PLATFORM_SUBTYPE_8909_PM660_V1 == platform_subtype) {
+			gpio_tlmm_config(spi_bkl_gpio.pin_id, 0,
+				spi_bkl_gpio.pin_direction,
+				spi_bkl_gpio.pin_pull,
+				spi_bkl_gpio.pin_strength,
+				spi_bkl_gpio.pin_state);
+			gpio_set(spi_bkl_gpio.pin_id, 2);
+		}
 	}
 
 	return 0;
@@ -364,6 +373,10 @@
 			((MSM8909W == platform) || (APQ8009W == platform)) &&
 			(HW_PLATFORM_MTP == hw_id))
 			regulator_enable(REG_LDO12 | REG_LDO5 | REG_LDO11 | REG_LDO18);
+		else if (pinfo->type == SPI_PANEL)
+		{
+			regulator_enable(REG_LDO11 | REG_LDO18);
+		}
 		else
 			regulator_enable(REG_LDO2 | REG_LDO6 | REG_LDO17);
 	}
@@ -392,7 +405,9 @@
 		  (HW_PLATFORM_SUBTYPE_DSDA2 == platform_subtype)) ||
 		 ((HW_PLATFORM_RCM == hw_id) &&
 		 ((HW_PLATFORM_SUBTYPE_SAP == platform_subtype)||
-		  (HW_PLATFORM_SUBTYPE_SAP_NOPMI == platform_subtype))))) {
+		  (HW_PLATFORM_SUBTYPE_SAP_NOPMI == platform_subtype))) ||
+		 ((HW_PLATFORM_MTP == hw_id) &&
+		 (HW_PLATFORM_SUBTYPE_INTRINSIC_SOM == platform_subtype)))) {
 		dprintf(INFO, "Splash disabled\n");
 		return true;
 	} else {
diff --git a/target/msm8953/init.c b/target/msm8953/init.c
index 19713a3..c2f1eb6 100644
--- a/target/msm8953/init.c
+++ b/target/msm8953/init.c
@@ -627,11 +627,6 @@
 	crypto_init_params(&ce_params);
 }
 
-void pmic_reset_configure(uint8_t reset_type)
-{
-	pm8994_reset_configure(reset_type);
-}
-
 uint32_t target_get_pmic()
 {
 	if (target_is_pmi_enabled()) {
@@ -646,6 +641,17 @@
 	}
 }
 
+void pmic_reset_configure(uint8_t reset_type)
+{
+	uint32_t pmi_type;
+
+	pmi_type = target_get_pmic();
+	if (pmi_type == PMIC_IS_PMI632)
+		pmi632_reset_configure(reset_type);
+	else
+		pm8994_reset_configure(reset_type);
+}
+
 struct qmp_reg qmp_settings[] =
 {
 	{0x804, 0x01}, /* USB3PHY_PCIE_USB3_PCS_POWER_DOWN_CONTROL */
diff --git a/target/msm8953/target_display.c b/target/msm8953/target_display.c
index 1a3864d..f276f64 100644
--- a/target/msm8953/target_display.c
+++ b/target/msm8953/target_display.c
@@ -55,18 +55,13 @@
 #include "include/display_resource.h"
 #include "gcdb_display.h"
 
-#define TRULY_1080P_VID_PANEL "truly_1080p_video"
-#define TRULY_1080P_CMD_PANEL "truly_1080p_cmd"
-
-#define HDMI_ADV_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_adv7533_1080p:cfg:single_dsi"
-#define TRULY_VID_PANEL_STRING "1:dsi:0:qcom,mdss_dsi_truly_1080p_video:1:none:cfg:single_dsi"
-#define TRULY_CMD_PANEL_STRING "1:dsi:0:qcom,mdss_dsi_truly_1080p_cmd:1:none:cfg:single_dsi"
-
 #define MAX_POLL_READS 15
 #define POLL_TIMEOUT_US 1000
 #define STRENGTH_SIZE_IN_BYTES	10
 #define REGULATOR_SIZE_IN_BYTES	5
 #define LANE_SIZE_IN_BYTES		20
+#define PWM_DUTY_US 13
+#define PWM_PERIOD_US 27
 /*---------------------------------------------------------------------------*/
 /* GPIO configuration                                                        */
 /*---------------------------------------------------------------------------*/
@@ -134,11 +129,24 @@
 	pm8x41_wled_config_slave_id(slave_id);
 	if (target_get_pmic() == PMIC_IS_PMI632) {
 		qpnp_lcdb_enable(enable);
-	}
-	else {
+	} else {
 		qpnp_wled_enable_backlight(enable);
 		qpnp_ibb_enable(enable);
 	}
+
+	return NO_ERROR;
+}
+
+static int pwm_backlight_ctrl(uint8_t enable)
+{
+	if(enable) {
+		pm_pwm_enable(false);
+		pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
+		pm_pwm_enable(true);
+	} else {
+		pm_pwm_enable(false);
+	}
+
 	return NO_ERROR;
 }
 
@@ -149,8 +157,11 @@
 	if (bl->bl_interface_type == BL_DCS)
 		return ret;
 
-	ret = wled_backlight_ctrl(enable);
-
+	if(target_get_pmic() == PMIC_IS_PMI632) {
+		ret = pwm_backlight_ctrl(enable);
+	} else {
+		ret = wled_backlight_ctrl(enable);
+	}
 	return ret;
 }
 
@@ -399,7 +410,6 @@
 	int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
 	bool ret = true;
 	struct oem_panel_data oem = mdss_dsi_get_oem_data();
-	uint32_t platform_subtype = board_hardware_subtype();
 
 	/*
 	 * if disable config is passed irrespective of
@@ -416,44 +426,6 @@
 		buf_size -= prefix_string_len;
 		pbuf += prefix_string_len;
 		strlcpy(pbuf, DISABLE_PANEL_STRING, buf_size);
-	} else if (platform_subtype == HW_PLATFORM_SUBTYPE_IOT) {
-		/* default to hdmi for apq iot */
-		if (!strcmp(oem.panel, "")) {
-			if (buf_size < (prefix_string_len +
-				strlen(HDMI_ADV_PANEL_STRING))) {
-				dprintf(CRITICAL, "HDMI command line argument \
-					is greater than buffer size\n");
-				return false;
-			}
-			strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-			buf_size -= prefix_string_len;
-			pbuf += prefix_string_len;
-			strlcpy(pbuf, HDMI_ADV_PANEL_STRING, buf_size);
-		} else if (!strcmp(oem.panel, TRULY_1080P_VID_PANEL)) {
-			if (buf_size < (prefix_string_len +
-				strlen(TRULY_VID_PANEL_STRING))) {
-				dprintf(CRITICAL, "TRULY VIDEO command line \
-					argument is greater than \
-					buffer size\n");
-				return false;
-			}
-			strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-			buf_size -= prefix_string_len;
-			pbuf += prefix_string_len;
-			strlcpy(pbuf, TRULY_VID_PANEL_STRING, buf_size);
-		} else if (!strcmp(oem.panel, TRULY_1080P_CMD_PANEL)) {
-			if (buf_size < (prefix_string_len +
-				strlen(TRULY_CMD_PANEL_STRING))) {
-				dprintf(CRITICAL, "TRULY CMD command line argument \
-					argument is greater than \
-					buffer size\n");
-				return false;
-			}
-			strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-			buf_size -= prefix_string_len;
-			pbuf += prefix_string_len;
-			strlcpy(pbuf, TRULY_CMD_PANEL_STRING, buf_size);
-		}
 	} else {
 		ret = gcdb_display_cmdline_arg(pbuf, buf_size);
 	}
@@ -466,7 +438,6 @@
 	struct oem_panel_data oem;
 	int32_t ret = 0;
 	uint32_t panel_loop = 0;
-	uint32_t platform_subtype = board_hardware_subtype();
 
 	set_panel_cmd_string(panel_name);
 	oem = mdss_dsi_get_oem_data();
@@ -483,10 +454,9 @@
 	}
 
 	/* skip splash screen completely not just cont splash */
-	if ((platform_subtype == HW_PLATFORM_SUBTYPE_IOT)
-		|| !strcmp(oem.panel, DISABLE_PANEL_CONFIG)) {
-		dprintf(INFO, "%s: Platform subtype %d\n",
-			__func__, platform_subtype);
+	if (!strcmp(oem.panel, DISABLE_PANEL_CONFIG)) {
+		dprintf(INFO, "%s: disable splash screen \n",
+			__func__);
 		return;
 	}
 
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 0293764..4ad64a3 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018 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,6 +76,12 @@
 
 #include <pm_smbchg_usb_chgpth.h>
 
+#if MOUNT_EMMC_LE
+       #define ROOTFS_EMMC_PATH " root=/dev/mmcblk0p"
+#else
+       #define ROOTFS_EMMC_PATH " root=/dev/mmcblock0p"
+#endif
+
 #define CE_INSTANCE             1
 #define CE_EE                   0
 #define CE_FIFO_SIZE            64
@@ -704,7 +710,7 @@
 	char lun_char_base = 'a', lun_char_limit = 'h';
 
 	/*allocate buflen for largest possible string*/
-	uint32_t buflen = strlen(" root=/dev/mmcblock0p") + sizeof(int) + 1; /*1 character for null termination*/
+	uint32_t buflen = strlen(ROOTFS_EMMC_PATH) + sizeof(int) + 1; /*1 character for null termination*/
 
 	if (!cmdline || !part ) {
 		dprintf(CRITICAL, "WARN: Invalid input param\n");
@@ -734,7 +740,7 @@
 	else
 	{
 		if (platform_boot_dev_isemmc()) {
-			snprintf(*buf, buflen, " root=/dev/mmcblock0p%d",
+			snprintf(*buf, buflen, ROOTFS_EMMC_PATH"%d",
 					system_ptn_index + 1);
 		} else {
 			lun = partition_get_lun(system_ptn_index);
diff --git a/target/target_display.c b/target/target_display.c
index 6904825..d32e90d 100644
--- a/target/target_display.c
+++ b/target/target_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015,2018 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
@@ -131,3 +131,18 @@
 {
 	return 0;
 }
+
+__WEAK int mdss_spi_init(void)
+{
+	return 0;
+}
+
+__WEAK int mdss_spi_panel_init(struct msm_panel_info *pinfo)
+{
+	return 0;
+}
+
+__WEAK int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+	return 0;
+}