Merge "app: aboot: Do not write protect devinfo for OTA"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f393bef..ca48092 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1581,6 +1581,8 @@
 #if USE_RPMB_FOR_DEVINFO
 		if (is_secure_boot_enable())
 			write_device_info_rpmb((void*) info, mmc_get_device_blocksize());
+		else
+			write_device_info_mmc(info);
 #else
 		write_device_info_mmc(info);
 #endif
@@ -1600,6 +1602,8 @@
 #if USE_RPMB_FOR_DEVINFO
 		if (is_secure_boot_enable())
 			read_device_info_rpmb((void*) info, mmc_get_device_blocksize());
+		else
+			read_device_info_mmc(info);
 #else
 		read_device_info_mmc(info);
 #endif
diff --git a/arch/arm/rules.mk b/arch/arm/rules.mk
index d822430..a4bf38c 100644
--- a/arch/arm/rules.mk
+++ b/arch/arm/rules.mk
@@ -132,22 +132,22 @@
 
 
 
-$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld
+$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%ROMLITE_PREFLASHED_DATA%/$(ROMLITE_PREFLASHED_DATA)/" < $< > $@
 
-$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld
+$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
 
-$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld
+$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
 
-$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld
+$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
 	@echo generating $@
 	@$(MKDIR)
 	$(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index 7862f9a..fafdae7 100755
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -415,7 +415,7 @@
 
 	dsi_id_len = strlen(dsi_id);
 	panel_node_len = strlen(panel_node);
-	if (!slave_panel_node || slave_panel_node == 0x0)
+	if (!slave_panel_node || !strcmp(slave_panel_node, ""))
 		slave_panel_node = NO_PANEL_CONFIG;
 	slave_panel_node_len = strlen(slave_panel_node);
 
diff --git a/dev/gcdb/display/panel_display.c b/dev/gcdb/display/panel_display.c
index d2675dc..d258db2 100755
--- a/dev/gcdb/display/panel_display.c
+++ b/dev/gcdb/display/panel_display.c
@@ -71,12 +71,26 @@
 		pinfo->mipi.phy_base = DSI0_PHY_BASE + base_offset;
 		pinfo->mipi.sctl_base = MIPI_DSI1_BASE + base1_offset;
 		pinfo->mipi.sphy_base = DSI1_PHY_BASE + base1_offset;
+		if (pinfo->mipi.use_dsi1_pll) {
+			dprintf(CRITICAL, "%s: Invalid combination: DSI0 controller + DSI1 PLL, using DSI0 PLL\n",
+				__func__);
+			pinfo->mipi.use_dsi1_pll = 0;
+		}
+		pinfo->mipi.pll_base = DSI0_PLL_BASE + base_offset;
+		pinfo->mipi.spll_base = DSI1_PLL_BASE + base1_offset;
 	} else if (!strcmp(panel_destination, "DISPLAY_2")) {
 		pinfo->dest = DISPLAY_2;
 		pinfo->mipi.ctl_base = MIPI_DSI1_BASE + base1_offset;
 		pinfo->mipi.phy_base = DSI1_PHY_BASE + base1_offset;
 		pinfo->mipi.sctl_base = MIPI_DSI0_BASE + base_offset;
 		pinfo->mipi.sphy_base = DSI0_PHY_BASE + base_offset;
+		if (pinfo->mipi.use_dsi1_pll) {
+			pinfo->mipi.pll_base = DSI1_PLL_BASE + base1_offset;
+			pinfo->mipi.spll_base = DSI0_PLL_BASE + base_offset;
+		} else {
+			pinfo->mipi.pll_base = DSI0_PLL_BASE + base_offset;
+			pinfo->mipi.spll_base = DSI1_PLL_BASE + base1_offset;
+		}
 	} else {
 		pinfo->dest = DISPLAY_UNKNOWN;
 		dprintf(CRITICAL, "%s: Unkown panel destination: %d\n",
@@ -84,9 +98,6 @@
 		return ERROR;
 	}
 
-	pinfo->mipi.pll_0_base = DSI0_PLL_BASE + base_offset;
-	pinfo->mipi.pll_1_base = DSI1_PLL_BASE + base1_offset;
-
 	/* Both DSI0 and DSI1 use the same regulator */
 	pinfo->mipi.reg_base = DSI0_REGULATOR_BASE + base_offset;
 	pinfo->mipi.sreg_base = DSI0_REGULATOR_BASE + base_offset;
@@ -94,8 +105,8 @@
 	dprintf(SPEW, "%s: panel dest=%s, ctl_base=0x%08x, phy_base=0x%08x\n",
 		__func__, panel_destination, pinfo->mipi.ctl_base,
 		pinfo->mipi.phy_base);
-	dprintf(SPEW, "pll_0_base=%08x, pll_1_base=0x%08x, reg_base=0x%08x, sreg_base=%08x\n",
-		pinfo->mipi.pll_0_base, pinfo->mipi.pll_1_base,
+	dprintf(SPEW, "pll_base=%08x, spll_base=0x%08x, reg_base=0x%08x, sreg_base=%08x\n",
+		pinfo->mipi.pll_base, pinfo->mipi.spll_base,
 		pinfo->mipi.reg_base, pinfo->mipi.sreg_base);
 	return NO_ERROR;
 }
@@ -178,6 +189,8 @@
 	pinfo->mipi.stream = pstruct->paneldata->dsi_stream;
 	if (pstruct->paneldata->panel_operating_mode & DUAL_DSI_FLAG)
 		pinfo->mipi.dual_dsi = 1;
+	if (pstruct->paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
+		pinfo->mipi.use_dsi1_pll = 1;
 	pinfo->mipi.mode_gpio_state = pstruct->paneldata->mode_gpio_state;
 	pinfo->mipi.bitclock = pstruct->paneldata->panel_bitclock_freq;
 	if (pinfo->mipi.bitclock) {
diff --git a/dev/gcdb/display/panel_display.h b/dev/gcdb/display/panel_display.h
index 8860f00..3fd78ae 100755
--- a/dev/gcdb/display/panel_display.h
+++ b/dev/gcdb/display/panel_display.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,6 +46,7 @@
 #define PIPE_SWAP_FLAG 0x4
 #define SPLIT_DISPLAY_FLAG 0x8
 #define DST_SPLIT_FLAG 0x10
+#define USE_DSI1_PLL_FLAG 0x20
 
 #define MAX_PANEL_ID_LEN 64
 #include "panel.h"
diff --git a/lib/openssl/crypto/md32_common.h b/lib/openssl/crypto/md32_common.h
index 1cb7839..40f5055 100644
--- a/lib/openssl/crypto/md32_common.h
+++ b/lib/openssl/crypto/md32_common.h
@@ -225,15 +225,13 @@
 #define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
-			 l|=(((unsigned long)(*((c)++)))    ),		\
-			 l)
+			 l|=(((unsigned long)(*((c)++)))    ))
 #endif
 #ifndef HOST_l2c
 #define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
-			 l)
+			 *((c)++)=(unsigned char)(((l)    )&0xff))
 #endif
 
 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
@@ -262,15 +260,13 @@
 #define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
-			 l|=(((unsigned long)(*((c)++)))<<24),		\
-			 l)
+			 l|=(((unsigned long)(*((c)++)))<<24))
 #endif
 #ifndef HOST_l2c
 #define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
-			 l)
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
 #endif
 
 #endif
diff --git a/platform/msm8909/platform.c b/platform/msm8909/platform.c
index 97c6838..8fcac08 100644
--- a/platform/msm8909/platform.c
+++ b/platform/msm8909/platform.c
@@ -40,10 +40,14 @@
 #define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
 #define A7_SS_SIZE    ((A7_SS_END - A7_SS_BASE)/MB)
 
-/* LK memory - cacheable, write through */
-#define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+/* LK memory - cacheable, write back */
+#define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
                                         MMU_MEMORY_AP_READ_WRITE)
 
+
+#define COMMON_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+                           MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
 /* Peripherals - non-shared device */
 #define IOMAP_MEMORY      (MMU_MEMORY_TYPE_DEVICE_SHARED | \
                         MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
@@ -58,6 +62,7 @@
 	{    MSM_IOMAP_BASE,    MSM_IOMAP_BASE,   MSM_IOMAP_SIZE,   IOMAP_MEMORY},
 	{    A7_SS_BASE,        A7_SS_BASE,       A7_SS_SIZE,       IOMAP_MEMORY},
 	{    SYSTEM_IMEM_BASE,  SYSTEM_IMEM_BASE, 1,                IMEM_MEMORY},
+	{    MSM_SHARED_BASE,   MSM_SHARED_BASE,  1,                COMMON_MEMORY},
 };
 
 static struct smem_ram_ptable ram_ptable;
@@ -131,7 +136,7 @@
 										sections * MB,
 										ptn_entry.start +
 										sections * MB,
-										(MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+										(MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
 										MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN));
 				}
 			}
diff --git a/platform/msm8916/acpuclock.c b/platform/msm8916/acpuclock.c
index 663a6ce..fd365be 100644
--- a/platform/msm8916/acpuclock.c
+++ b/platform/msm8916/acpuclock.c
@@ -440,12 +440,17 @@
 
 	struct clk *qup_clk;
 
-	if((blsp_id != BLSP_ID_1) || (qup_id != QUP_ID_1)) {
+	if((blsp_id != BLSP_ID_1) || ((qup_id != QUP_ID_1) && (qup_id != QUP_ID_3))) {
 		dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
 		ASSERT(0);
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "blsp1_qup2_ahb_iface_clk");
+	if (qup_id == QUP_ID_1) {
+		snprintf(clk_name, sizeof(clk_name), "blsp1_qup2_ahb_iface_clk");
+	}
+	else if (qup_id == QUP_ID_3) {
+		snprintf(clk_name, sizeof(clk_name), "blsp1_qup4_ahb_iface_clk");
+	}
 
 	ret = clk_get_set_enable(clk_name, 0 , 1);
 
@@ -454,7 +459,12 @@
 		return;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup2_i2c_apps_clk");
+	if (qup_id == QUP_ID_1) {
+		snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup2_i2c_apps_clk");
+	}
+	else if (qup_id == QUP_ID_3) {
+		snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup4_i2c_apps_clk");
+	}
 
 	qup_clk = clk_get(clk_name);
 
diff --git a/platform/msm8916/gpio.c b/platform/msm8916/gpio.c
index 2453b33..145b81c 100644
--- a/platform/msm8916/gpio.c
+++ b/platform/msm8916/gpio.c
@@ -81,6 +81,15 @@
 				gpio_tlmm_config(7, 3, GPIO_OUTPUT, GPIO_NO_PULL,
 					GPIO_8MA, GPIO_DISABLE);
 			break;
+			case QUP_ID_3:
+				/* configure I2C SDA gpio */
+				gpio_tlmm_config(14, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+						GPIO_8MA, GPIO_DISABLE);
+
+				/* configure I2C SCL gpio */
+				gpio_tlmm_config(15, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+					GPIO_8MA, GPIO_DISABLE);
+			break;
 			default:
 				dprintf(CRITICAL, "Incorrect QUP id %d\n",qup_id);
 				ASSERT(0);
diff --git a/platform/msm8916/include/platform/iomap.h b/platform/msm8916/include/platform/iomap.h
index 2d9197c..494f6cf 100644
--- a/platform/msm8916/include/platform/iomap.h
+++ b/platform/msm8916/include/platform/iomap.h
@@ -84,6 +84,11 @@
 #define TLMM_BASE_ADDR              0x1000000
 #define GPIO_CONFIG_ADDR(x)         (TLMM_BASE_ADDR + (x)*0x1000)
 #define GPIO_IN_OUT_ADDR(x)         (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000)
+#define GPIO_OUT_SET_ADDR(x)        (TLMM_BASE_ADDR + 0x200040 + (x/32)*0x04)
+#define GPIO_OUT_CLR_ADDR(x)        (TLMM_BASE_ADDR + 0x200020 + (x/32)*0x04)
+#define GPIO_OUT_VAL(x)             (1 << (x - (x/32)*32))
+#define GPIO_OUT_OE_SET_ADDR(x)     (TLMM_BASE_ADDR + 0x2000C0 + (x/32)*0x04)
+#define GPIO_OUT_OE_VAL(x)          (1 << (x - (x/32)*32))
 
 #define MPM2_MPM_CTRL_BASE          0x004A0000
 #define MPM2_MPM_PS_HOLD            0x004AB000
@@ -105,6 +110,10 @@
 #define GCC_BLSP1_QUP2_CFG_RCGR     (CLK_CTL_BASE + 0x3018)
 #define GCC_BLSP1_QUP2_CMD_RCGR     (CLK_CTL_BASE + 0x3014)
 
+#define GCC_BLSP1_QUP4_APPS_CBCR    (CLK_CTL_BASE + 0x5020)
+#define GCC_BLSP1_QUP4_CFG_RCGR     (CLK_CTL_BASE + 0x5004)
+#define GCC_BLSP1_QUP4_CMD_RCGR     (CLK_CTL_BASE + 0x5000)
+
 /* GPLL */
 #define GPLL0_STATUS                (CLK_CTL_BASE + 0x2101C)
 #define GPLL1_STATUS                (CLK_CTL_BASE + 0x2001C)
diff --git a/platform/msm8916/msm8916-clock.c b/platform/msm8916/msm8916-clock.c
index c2ec604..43df860 100644
--- a/platform/msm8916/msm8916-clock.c
+++ b/platform/msm8916/msm8916-clock.c
@@ -562,6 +562,31 @@
 		.ops      = &clk_ops_branch,
 	},
 };
+
+static struct rcg_clk gcc_blsp1_qup4_i2c_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP4_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP4_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+	.cbcr_reg = (uint32_t *) GCC_BLSP1_QUP4_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup4_i2c_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 /* Clock lookup table */
 static struct clk_lookup msm_clocks_8916[] =
 {
@@ -593,6 +618,10 @@
 	CLK_LOOKUP("blsp1_qup2_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
 	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk_src", gcc_blsp1_qup2_i2c_apps_clk_src.c),
 	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk", gcc_blsp1_qup2_i2c_apps_clk.c),
+
+	CLK_LOOKUP("blsp1_qup4_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup4_i2c_apps_clk_src", gcc_blsp1_qup4_i2c_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup4_i2c_apps_clk", gcc_blsp1_qup4_i2c_apps_clk.c),
 };
 
 void msm8939_clock_override()
diff --git a/platform/msm8994/acpuclock.c b/platform/msm8994/acpuclock.c
index 0b64ce0..6f4e0f0 100644
--- a/platform/msm8994/acpuclock.c
+++ b/platform/msm8994/acpuclock.c
@@ -455,18 +455,18 @@
 	clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
 }
 
-void mmss_dsi_clock_enable(uint32_t dsi_pixel0_cfg_rcgr, uint32_t flags,
+void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t flags,
 			uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
 {
 	int ret;
 
 	if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
 		/* Enable DSI0 branch clocks */
-		writel(0x100, DSI_BYTE0_CFG_RCGR);
+		writel(cfg_rcgr, DSI_BYTE0_CFG_RCGR);
 		writel(0x1, DSI_BYTE0_CMD_RCGR);
 		writel(0x1, DSI_BYTE0_CBCR);
 
-		writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
+		writel(cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
 		writel(0x1, DSI_PIXEL0_CMD_RCGR);
 		writel(0x1, DSI_PIXEL0_CBCR);
 
@@ -484,11 +484,11 @@
 
 	if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
 		/* Enable DSI1 branch clocks */
-		writel(0x100, DSI_BYTE1_CFG_RCGR);
+		writel(cfg_rcgr, DSI_BYTE1_CFG_RCGR);
 		writel(0x1, DSI_BYTE1_CMD_RCGR);
 		writel(0x1, DSI_BYTE1_CBCR);
 
-		writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
+		writel(cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
 		writel(0x1, DSI_PIXEL1_CMD_RCGR);
 		writel(0x1, DSI_PIXEL1_CBCR);
 
diff --git a/platform/msm8994/include/platform/clock.h b/platform/msm8994/include/platform/clock.h
index 72d9787..ac611eb 100644
--- a/platform/msm8994/include/platform/clock.h
+++ b/platform/msm8994/include/platform/clock.h
@@ -79,6 +79,7 @@
 #define DSI_PIXEL0_D                    REG_MM(0x2010)
 
 #define DSI0_PHY_PLL_OUT                BIT(8)
+#define DSI1_PHY_PLL_OUT                BIT(9)
 #define PIXEL_SRC_DIV_1_5               BIT(1)
 
 #define DSI_BYTE1_CMD_RCGR              REG_MM(0x2140)
@@ -122,7 +123,7 @@
 void clock_ce_disable(uint8_t instance);
 void clock_usb30_init(void);
 
-void mmss_dsi_clock_enable(uint32_t dsi_pixel0_cfg_rcgr, uint32_t dual_dsi,
+void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t dual_dsi,
 	uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d);
 void mmss_dsi_clock_disable(uint32_t dual_dsi);
 void mmss_bus_clock_enable(void);
diff --git a/platform/msm8994/platform.c b/platform/msm8994/platform.c
index eaaadc0..12b1039 100644
--- a/platform/msm8994/platform.c
+++ b/platform/msm8994/platform.c
@@ -39,6 +39,9 @@
 
 #define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
 
+#define HLOS_MEMORY_START 0x0
+#define HLOS_MEMORY_SIZE  0x63
+
 /* LK memory - cacheable, write through */
 #define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
                            MMU_MEMORY_AP_READ_WRITE)
@@ -48,14 +51,17 @@
                            MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
 
 /* IMEM memory - cacheable, write through */
-#define IMEM_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+#define COMMON_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
                            MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
 
 static mmu_section_t mmu_section_table[] = {
-/*       Physical addr,    Virtual addr,     Size (in MB),    Flags */
-	{    MEMBASE,          MEMBASE,          (MEMSIZE / MB),   LK_MEMORY},
-	{    MSM_IOMAP_BASE,   MSM_IOMAP_BASE,   MSM_IOMAP_SIZE,  IOMAP_MEMORY},
-	{    SYSTEM_IMEM_BASE, SYSTEM_IMEM_BASE, 1,              IMEM_MEMORY},
+/*       Physical addr,     Virtual addr,      Size (in MB),        Flags */
+	{    MEMBASE,           MEMBASE,           (MEMSIZE / MB),      LK_MEMORY},
+	{    MSM_IOMAP_BASE,    MSM_IOMAP_BASE,    MSM_IOMAP_SIZE,      IOMAP_MEMORY},
+	{    SYSTEM_IMEM_BASE,  SYSTEM_IMEM_BASE,  1,                   COMMON_MEMORY},
+	{    MSM_SHARED_BASE,   MSM_SHARED_BASE,   2,                   COMMON_MEMORY},
+	{    HLOS_MEMORY_START, HLOS_MEMORY_START, HLOS_MEMORY_SIZE,    COMMON_MEMORY},
+	{    SCRATCH_ADDR,      SCRATCH_ADDR,      (SCRATCH_SIZE / MB), COMMON_MEMORY},
 };
 
 void platform_early_init(void)
@@ -95,40 +101,7 @@
 {
 	uint32_t i;
 	uint32_t sections;
-	ram_partition ptn_entry;
 	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
-	uint32_t len = 0;
-
-	ASSERT(smem_ram_ptable_init_v1());
-
-	len = smem_get_ram_ptable_len();
-
-	/* Configure the MMU page entries for SDRAM and IMEM memory read
-	   from the smem ram table*/
-	for(i = 0; i < len; i++)
-	{
-		smem_get_ram_ptable_entry(&ptn_entry, i);
-		if(ptn_entry.type == SYS_MEMORY)
-		{
-			if((ptn_entry.category == SDRAM) ||
-			   (ptn_entry.category == IMEM))
-			{
-				/* Check to ensure that start address is 1MB aligned */
-				ASSERT((ptn_entry.start & (MB-1)) == 0);
-
-				sections = (ptn_entry.size) / MB;
-				while(sections--)
-				{
-					arm_mmu_map_section(ptn_entry.start +
-										sections * MB,
-										ptn_entry.start +
-										sections * MB,
-										(MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
-										 MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN));
-				}
-			}
-		}
-	}
 
 	/* Configure the MMU page entries for memory read from the
 	   mmu_section_table */
diff --git a/platform/msm_shared/include/mipi_dsi.h b/platform/msm_shared/include/mipi_dsi.h
index c2ddd9b..d63a877 100644
--- a/platform/msm_shared/include/mipi_dsi.h
+++ b/platform/msm_shared/include/mipi_dsi.h
@@ -256,7 +256,7 @@
 	int rdbk_len);
 int32_t mdss_dsi_auto_pll_config(uint32_t pll_base, uint32_t ctl_base,
 	struct mdss_dsi_pll_config *pd);
-void mdss_dsi_auto_pll_20nm_config(uint32_t pll_base, uint32_t pll_1_base,
+void mdss_dsi_auto_pll_20nm_config(uint32_t pll_base, uint32_t spll_base,
 		struct mdss_dsi_pll_config *pd);
 void mdss_dsi_pll_20nm_sw_reset_st_machine(uint32_t pll_base);
 uint32_t mdss_dsi_pll_20nm_lock_status(uint32_t pll_base);
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index 75870a2..ff99ba3 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -245,6 +245,7 @@
 	char force_clk_lane_hs;
 	char lane_swap;
 	uint8_t dual_dsi;
+	uint8_t use_dsi1_pll;
 	uint8_t broadcast;
 	uint8_t mode_gpio_state;
 	uint32_t signature;
@@ -255,8 +256,8 @@
 	uint32_t sphy_base;
 	uint32_t reg_base;
 	uint32_t sreg_base;
-	uint32_t pll_0_base;
-	uint32_t pll_1_base;
+	uint32_t pll_base;
+	uint32_t spll_base;
 
 	struct dfps_pll_codes pll_codes;
 };
diff --git a/platform/msm_shared/mipi_dsi_autopll_20nm.c b/platform/msm_shared/mipi_dsi_autopll_20nm.c
index da0551e..e6f326f 100644
--- a/platform/msm_shared/mipi_dsi_autopll_20nm.c
+++ b/platform/msm_shared/mipi_dsi_autopll_20nm.c
@@ -281,15 +281,16 @@
 }
 
 
-void mdss_dsi_auto_pll_20nm_config(uint32_t pll_base, uint32_t pll_1_base,
+void mdss_dsi_auto_pll_20nm_config(uint32_t pll_base, uint32_t spll_base,
 	struct mdss_dsi_pll_config *pd)
 {
 	/*
-	 * For 20nm PHY, DSI PLL 1 drains some current in its reset state.
-	 * Need to turn off the DSI1 PLL explicitly.
+	 * For 20nm PHY, the DSI PLL which is not powered on to drive a panel
+	 * drains some current in its reset state.
+	 * Need to turn off that PLL explicitly.
 	 */
-	mdss_dsi_pll_20nm_config_common_block_1(pll_1_base);
-	mdss_dsi_pll_20nm_config_powerdown(pll_1_base);
+	mdss_dsi_pll_20nm_config_common_block_1(spll_base);
+	mdss_dsi_pll_20nm_config_powerdown(spll_base);
 
 	mdss_dsi_pll_20nm_config_common_block_1(pll_base);
 	mdss_dsi_pll_20nm_config_common_block_2(pll_base);
diff --git a/platform/msm_shared/rpm-glink.c b/platform/msm_shared/rpm-glink.c
index 01cae61..4b74c98 100644
--- a/platform/msm_shared/rpm-glink.c
+++ b/platform/msm_shared/rpm-glink.c
@@ -53,6 +53,7 @@
 
 glink_handle_type rpm_glink_port, ssr_glink_port;
 static uint32_t msg_id;
+static event_t wait_for_init;
 static event_t wait_for_data;
 
 extern glink_err_type glink_wait_link_down(glink_handle_type handle);
@@ -261,6 +262,7 @@
 {
 	if(event == GLINK_CONNECTED)
 	{
+		event_signal(&wait_for_init, false);
 		dprintf(INFO, "Glink Connection between APPS and RPM established\n");
 		return;
 	}
@@ -319,6 +321,7 @@
 {
 	glink_err_type ret;
 	glink_link_id_type link_id;
+	event_init(&wait_for_init, false, EVENT_FLAG_AUTOUNSIGNAL);
 
 	dprintf(INFO, "RPM GLink Init\n");
 	// Initialize RPM transport
@@ -336,6 +339,7 @@
 		dprintf(CRITICAL, "RPM Glink Init Failure\n");
 		ASSERT(0);
 	}
+	event_wait(&wait_for_init);
 }
 
 void rpm_glink_uninit()
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index 54a82db..caaec78 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -878,6 +878,10 @@
 	/* Write the command register */
 	REG_WRITE16(host, SDHCI_PREP_CMD(cmd->cmd_index, flags), SDHCI_CMD_REG);
 
+#if USE_TARGET_HS200_DELAY
+	udelay(1000);
+#endif
+
 	/* Command complete sequence */
 	if (sdhci_cmd_complete(host, cmd))
 	{
diff --git a/project/msm8952.mk b/project/msm8952.mk
index b20e243..c0484d0 100644
--- a/project/msm8952.mk
+++ b/project/msm8952.mk
@@ -60,3 +60,5 @@
 DEFINES += PLATFORM_USE_SCM_DLOAD=1
 
 CFLAGS += -Werror
+
+DEFINES += USE_TARGET_HS200_DELAY=1
diff --git a/project/msm8996.mk b/project/msm8996.mk
index dfe74cf..664c0ae 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -20,6 +20,7 @@
 ENABLE_QGIC3 := 1
 ENABLE_PARTIAL_GOODS_SUPPORT := 1
 ENABLE_RPMB_SUPPORT := 1
+ENABLE_GLINK_SUPPORT := 1
 
 DEFINES +=VIRTIO=1
 
@@ -43,6 +44,10 @@
 #Disable thumb mode
 ENABLE_THUMB := false
 
+ifeq ($(ENABLE_GLINK_SUPPORT),1)
+DEFINES += GLINK_SUPPORT=1
+endif
+
 ifeq ($(EMMC_BOOT),1)
 DEFINES += _EMMC_BOOT=1
 endif
diff --git a/target/apq8084/target_display.c b/target/apq8084/target_display.c
index b46ef08..20e4d03 100755
--- a/target/apq8084/target_display.c
+++ b/target/apq8084/target_display.c
@@ -178,9 +178,9 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_0_base,
+		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
 						pinfo->mipi.ctl_base, pll_data);
-		dsi_pll_enable_seq(pinfo->mipi.pll_0_base);
+		dsi_pll_enable_seq(pinfo->mipi.pll_base);
 		mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi,
 					pll_data->pclk_m,
 					pll_data->pclk_n,
diff --git a/target/msm8226/target_display.c b/target/msm8226/target_display.c
index 77ca16e..fe2e6d5 100755
--- a/target/msm8226/target_display.c
+++ b/target/msm8226/target_display.c
@@ -308,9 +308,9 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_0_base,
+		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
 				pinfo->mipi.ctl_base, pll_data);
-		dsi_pll_enable_seq(pinfo->mipi.pll_0_base);
+		dsi_pll_enable_seq(pinfo->mipi.pll_base);
 		mmss_dsi_clocks_enable(pll_data->pclk_m,
 				pll_data->pclk_n,
 				pll_data->pclk_d);
diff --git a/target/msm8909/target_display.c b/target/msm8909/target_display.c
index 3f2a493..e949547 100755
--- a/target/msm8909/target_display.c
+++ b/target/msm8909/target_display.c
@@ -166,10 +166,10 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		mdss_dsi_uniphy_pll_sw_reset_8909(DSI0_PLL_BASE);
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_0_base,
+		mdss_dsi_uniphy_pll_sw_reset_8909(pinfo->mipi.pll_base);
+		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
 						pinfo->mipi.ctl_base, pll_data);
-		if (!dsi_pll_enable_seq_8909(pinfo->mipi.pll_0_base))
+		if (!dsi_pll_enable_seq_8909(pinfo->mipi.pll_base))
 			dprintf(CRITICAL, "Not able to enable the pll\n");
 		gcc_dsi_clocks_enable(pll_data->pclk_m,
 				pll_data->pclk_n,
diff --git a/target/msm8916/target_display.c b/target/msm8916/target_display.c
index 43a2903..42693d6 100644
--- a/target/msm8916/target_display.c
+++ b/target/msm8916/target_display.c
@@ -236,10 +236,10 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		mdss_dsi_uniphy_pll_sw_reset_8916(DSI0_PLL_BASE);
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_0_base,
+		mdss_dsi_uniphy_pll_sw_reset_8916(pinfo->mipi.pll_base);
+		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
 						pinfo->mipi.ctl_base, pll_data);
-		if (!dsi_pll_enable_seq_8916(pinfo->mipi.pll_0_base))
+		if (!dsi_pll_enable_seq_8916(pinfo->mipi.pll_base))
 			dprintf(CRITICAL, "Not able to enable the pll\n");
 		gcc_dsi_clocks_enable(pinfo->mipi.dual_dsi, pll_data->pclk_m,
 				pll_data->pclk_n,
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 23976fd..9a86cd9 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -246,10 +246,10 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		mdss_dsi_uniphy_pll_sw_reset_8952(DSI0_PLL_BASE);
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_0_base,
+		mdss_dsi_uniphy_pll_sw_reset_8952(pinfo->mipi.pll_base);
+		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
 						pinfo->mipi.ctl_base, pll_data);
-		if (!dsi_pll_enable_seq_8952(pinfo->mipi.pll_0_base))
+		if (!dsi_pll_enable_seq_8952(pinfo->mipi.pll_base))
 			dprintf(CRITICAL, "Not able to enable the pll\n");
 		gcc_dsi_clocks_enable(pll_data->pclk_m, pll_data->pclk_n,
 				pll_data->pclk_d);
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index 6224f31..73319ea 100755
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -247,9 +247,9 @@
 	if (enable) {
 		mdp_gdsc_ctrl(enable);
 		mdp_clock_init();
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_0_base,
+		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
 						pinfo->mipi.ctl_base, pll_data);
-		dsi_pll_enable_seq(pinfo->mipi.pll_0_base);
+		dsi_pll_enable_seq(pinfo->mipi.pll_base);
 		mmss_clock_auto_pll_init(DSI0_PHY_PLL_OUT, dual_dsi,
 					pll_data->pclk_m,
 					pll_data->pclk_n,
diff --git a/target/msm8994/meminfo.c b/target/msm8994/meminfo.c
index cb8c726..b0eec92 100644
--- a/target/msm8994/meminfo.c
+++ b/target/msm8994/meminfo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -84,5 +84,5 @@
 
 unsigned target_get_max_flash_size(void)
 {
-	return (512 * 1024 * 1024);
+	return SCRATCH_SIZE;
 }
diff --git a/target/msm8994/rules.mk b/target/msm8994/rules.mk
index 9c02201..16fd384 100644
--- a/target/msm8994/rules.mk
+++ b/target/msm8994/rules.mk
@@ -12,6 +12,8 @@
 
 SCRATCH_ADDR := 0x10000000
 
+SCRATCH_SIZE := 0x20000000
+
 DEFINES += DISPLAY_SPLASH_SCREEN=1
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
@@ -34,7 +36,8 @@
 	TAGS_ADDR=$(TAGS_ADDR) \
 	KERNEL_ADDR=$(KERNEL_ADDR) \
 	RAMDISK_ADDR=$(RAMDISK_ADDR) \
-	SCRATCH_ADDR=$(SCRATCH_ADDR)
+	SCRATCH_ADDR=$(SCRATCH_ADDR) \
+	SCRATCH_SIZE=$(SCRATCH_SIZE)
 
 
 OBJS += \
diff --git a/target/msm8994/target_display.c b/target/msm8994/target_display.c
index 71fc136..1779ea5 100644
--- a/target/msm8994/target_display.c
+++ b/target/msm8994/target_display.c
@@ -389,7 +389,7 @@
 {
 	uint32_t ret = NO_ERROR;
 	struct mdss_dsi_pll_config *pll_data;
-	uint32_t flags;
+	uint32_t flags, dsi_phy_pll_out;
 	struct dfps_pll_codes *pll_codes = &pinfo->mipi.pll_codes;
 
 	if (pinfo->dest == DISPLAY_2) {
@@ -421,23 +421,28 @@
 		goto clks_disable;
 	}
 
-	mdss_dsi_auto_pll_20nm_config(pinfo->mipi.pll_0_base,
-		pinfo->mipi.pll_1_base, pll_data);
+	mdss_dsi_auto_pll_20nm_config(pinfo->mipi.pll_base,
+		pinfo->mipi.spll_base, pll_data);
 
-	if (!dsi_pll_20nm_enable_seq(pinfo->mipi.pll_0_base)) {
+	if (!dsi_pll_20nm_enable_seq(pinfo->mipi.pll_base)) {
 		ret = ERROR;
 		dprintf(CRITICAL, "PLL failed to lock!\n");
 		goto clks_disable;
 	}
 
-	pll_codes->codes[0] = readl_relaxed(pinfo->mipi.pll_0_base +
+	pll_codes->codes[0] = readl_relaxed(pinfo->mipi.pll_base +
 		MMSS_DSI_PHY_PLL_CORE_KVCO_CODE);
-	pll_codes->codes[1] = readl_relaxed(pinfo->mipi.pll_0_base +
+	pll_codes->codes[1] = readl_relaxed(pinfo->mipi.pll_base +
 		MMSS_DSI_PHY_PLL_CORE_VCO_TUNE);
 	dprintf(SPEW, "codes %d %d\n", pll_codes->codes[0],
 		pll_codes->codes[1]);
 
-	mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, flags,
+	if (pinfo->mipi.use_dsi1_pll)
+		dsi_phy_pll_out = DSI1_PHY_PLL_OUT;
+	else
+		dsi_phy_pll_out = DSI0_PHY_PLL_OUT;
+
+	mmss_dsi_clock_enable(dsi_phy_pll_out, flags,
 		pll_data->pclk_m,
 		pll_data->pclk_n,
 		pll_data->pclk_d);
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 2fd32d8..57695d8 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -40,6 +40,7 @@
 #include <board.h>
 #include <smem.h>
 #include <baseband.h>
+#include <regulator.h>
 #include <dev/keys.h>
 #include <pm8x41.h>
 #include <crypto5_wrapper.h>
@@ -56,6 +57,7 @@
 #include <sdhci_msm.h>
 #include <qusb2_phy.h>
 #include <rpmb.h>
+#include <rpm-glink.h>
 
 #define CE_INSTANCE             1
 #define CE_EE                   1
@@ -147,6 +149,9 @@
 		}
 	}
 
+	/* Tear down glink channels */
+	rpm_glink_uninit();
+
 	if (rpmb_uninit() < 0)
 	{
 		dprintf(CRITICAL, "RPMB uninit failed\n");
@@ -261,6 +266,9 @@
 		dprintf(CRITICAL, "RPMB init failed\n");
 		ASSERT(0);
 	}
+	/* Initialize Glink */
+	rpm_glink_init();
+
 }
 
 unsigned board_machtype(void)
diff --git a/target/msm8996/regulator.c b/target/msm8996/regulator.c
new file mode 100644
index 0000000..909082d
--- /dev/null
+++ b/target/msm8996/regulator.c
@@ -0,0 +1,108 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Fundation, 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 <stdlib.h>
+#include <regulator.h>
+#include <rpm-ipc.h>
+#include <bits.h>
+
+static uint32_t ldo2[][11]=
+{
+	{
+		LDOA_RES_TYPE, 2,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 2,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 1250000,
+		KEY_CURRENT, 4, 16,
+	},
+};
+
+static uint32_t ldo14[][11]=
+{
+	{
+		LDOA_RES_TYPE, 14,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 14,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 1800000,
+		KEY_CURRENT, 4, 52,
+	},
+};
+
+static uint32_t ldo28[][14]=
+{
+	{
+		LDOA_RES_TYPE, 28,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 28,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 1000000,
+		KEY_CURRENT, 4, 72,
+	},
+
+};
+
+void regulator_enable(uint32_t enable)
+{
+	if (enable & REG_LDO2)
+		rpm_send_data(&ldo2[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO14)
+		rpm_send_data(&ldo14[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO28)
+		rpm_send_data(&ldo28[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+}
+
+void regulator_disable(uint32_t enable)
+{
+	if (enable & REG_LDO2)
+		rpm_send_data(&ldo2[GENERIC_DISABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO14)
+		rpm_send_data(&ldo14[GENERIC_DISABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO28)
+		rpm_send_data(&ldo28[GENERIC_DISABLE][0], 36, RPM_REQUEST_TYPE);
+}
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index 28ab538..2326ff0 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -38,4 +38,9 @@
 
 OBJS += \
 	$(LOCAL_DIR)/init.o \
-	$(LOCAL_DIR)/meminfo.o \
+	$(LOCAL_DIR)/meminfo.o
+
+ifeq ($(ENABLE_GLINK_SUPPORT),1)
+OBJS += \
+    $(LOCAL_DIR)/regulator.o
+endif