Merge "dev: gcdb: Change the vertical back porch value for nt33590 panel"
diff --git a/arch/arm/cache-ops.S b/arch/arm/cache-ops.S
index 974fb9b..e67dc65 100644
--- a/arch/arm/cache-ops.S
+++ b/arch/arm/cache-ops.S
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -338,7 +338,7 @@
 	bhs		0b
 	
 	mov		r0, #0
-	mcr		p15, 0, r0, c7, c10, 4		// data sync barrier (formerly drain write buffer)
+	dsb
 
 	bx		lr
 
@@ -351,7 +351,7 @@
 	bhs		0b
 
 	mov		r0, #0
-	mcr		p15, 0, r0, c7, c10, 4		// data sync barrier (formerly drain write buffer)
+	dsb
 
 	bx		lr
 
@@ -364,8 +364,7 @@
 	subs	r1, r1, #CACHE_LINE
 	bhs		0b
 	mov		r0, #0
-	/* data sync barrier (formerly drain write buffer*/
-	mcr		p15, 0, r0, c7, c10, 4
+	dsb
 	bx		lr
 
 	/* void arch_sync_cache_range(addr_t start, size_t len); */
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 1e9f16c..8268ed2 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -29,7 +29,11 @@
 #include <bits.h>
 #include <debug.h>
 #include <reg.h>
+#if SPMI_CORE_V2
+#include <spmi_v2.h>
+#else
 #include <spmi.h>
+#endif
 #include <string.h>
 #include <pm8x41_hw.h>
 #include <pm8x41.h>
diff --git a/platform/msm8916/acpuclock.c b/platform/msm8916/acpuclock.c
index 9197be9..06a2c06 100644
--- a/platform/msm8916/acpuclock.c
+++ b/platform/msm8916/acpuclock.c
@@ -38,55 +38,135 @@
 
 void hsusb_clock_init(void)
 {
+	int ret;
+	struct clk *iclk, *cclk;
 
+	ret = clk_get_set_enable("usb_iface_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb_core_clk", 80000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	mdelay(20);
+
+	iclk = clk_get("usb_iface_clk");
+	cclk = clk_get("usb_core_clk");
+
+	clk_disable(iclk);
+	clk_disable(cclk);
+
+	mdelay(20);
+
+	/* Start the block reset for usb */
+	writel(1, USB_HS_BCR);
+
+	mdelay(20);
+
+	/* Take usb block out of reset */
+	writel(0, USB_HS_BCR);
+
+	mdelay(20);
+
+	ret = clk_enable(iclk);
+
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_enable(cclk);
+
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
+		ASSERT(0);
+	}
 }
 
 void clock_init_mmc(uint32_t interface)
 {
+	char clk_name[64];
+	int ret;
 
+	snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
+
+	/* enable interface clock */
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
 }
 
 /* Configure MMC clock */
 void clock_config_mmc(uint32_t interface, uint32_t freq)
 {
-	mmc_boot_mci_clk_enable();
+	int ret;
+	uint32_t reg;
+	char clk_name[64];
+
+	snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
+
+	if(freq == MMC_CLK_400KHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 400000, 1);
+	}
+	else if(freq == MMC_CLK_50MHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 50000000, 1);
+	}
+	else if(freq == MMC_CLK_200MHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 200000000, 1);
+	}
+	else if(freq == MMC_CLK_177MHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 177770000, 1);
+	}
+	else
+	{
+		dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
+		ASSERT(0);
+	}
+
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret);
+		ASSERT(0);
+	}
 }
 
 /* Configure UART clock based on the UART block id*/
 void clock_config_uart_dm(uint8_t id)
 {
+	int ret;
+	char iclk[64];
+	char cclk[64];
 
-}
+	snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
+	snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
 
-/* Function to asynchronously reset CE.
- * Function assumes that all the CE clocks are off.
- */
-static void ce_async_reset(uint8_t instance)
-{
+	ret = clk_get_set_enable(iclk, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
+		ASSERT(0);
+	}
 
-}
-
-static void clock_ce_enable(uint8_t instance)
-{
-
-}
-
-static void clock_ce_disable(uint8_t instance)
-{
-
-}
-
-void clock_config_ce(uint8_t instance)
-{
-	/* Need to enable the clock before disabling since the clk_disable()
-	 * has a check to default to nop when the clk_enable() is not called
-	 * on that particular clock.
-	 */
-	clock_ce_enable(instance);
-
-	clock_ce_disable(instance);
-
-	ce_async_reset(instance);
-
-	clock_ce_enable(instance);
+	ret = clk_get_set_enable(cclk, 7372800, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
+		ASSERT(0);
+	}
 }
diff --git a/platform/msm8916/gpio.c b/platform/msm8916/gpio.c
index 1eb900e..3035047 100644
--- a/platform/msm8916/gpio.c
+++ b/platform/msm8916/gpio.c
@@ -44,12 +44,33 @@
 	return;
 }
 
-void gpio_set(uint32_t gpio, uint32_t dir)
+void gpio_set_dir(uint32_t gpio, uint32_t dir)
 {
 	writel(dir, (uint32_t *)GPIO_IN_OUT_ADDR(gpio));
 	return;
 }
 
+void gpio_set_value(uint32_t gpio, uint32_t value)
+{
+	/* GPIO_OUTPUT */
+	if (value) {
+		writel(GPIO_OUT_VAL(gpio),
+			(uint32_t *)GPIO_OUT_SET_ADDR(gpio));
+	} else {
+		writel(GPIO_OUT_VAL(gpio),
+			(uint32_t *)GPIO_OUT_CLR_ADDR(gpio));
+	}
+	/* GPIO_OE */
+	writel(GPIO_OUT_OE_VAL(gpio),
+			(uint32_t *)GPIO_OUT_OE_SET_ADDR(gpio));
+	return;
+}
+
+uint32_t gpio_status(uint32_t gpio)
+{
+	return readl(GPIO_IN_OUT_ADDR(gpio)) & GPIO_IN;
+}
+
 /* Configure gpio for blsp uart 2 */
 void gpio_config_uart_dm(uint8_t id)
 {
diff --git a/platform/msm8916/include/platform/gpio.h b/platform/msm8916/include/platform/gpio.h
index 2e7c070..12d9fe2 100644
--- a/platform/msm8916/include/platform/gpio.h
+++ b/platform/msm8916/include/platform/gpio.h
@@ -29,6 +29,9 @@
 #ifndef __PLATFORM_MSM8916_GPIO_H
 #define __PLATFORM_MSM8916_GPIO_H
 
+#include <bits.h>
+#include <gpio.h>
+
 /* GPIO TLMM: Direction */
 #define GPIO_INPUT      0
 #define GPIO_OUTPUT     1
@@ -53,6 +56,18 @@
 #define GPIO_ENABLE     0
 #define GPIO_DISABLE    1
 
-void gpio_config_uart_dm(uint8_t id);
+/* GPIO_IN_OUT register shifts. */
+#define GPIO_IN         BIT(0)
+#define GPIO_OUT        BIT(1)
 
+void gpio_config_uart_dm(uint8_t id);
+uint32_t gpio_status(uint32_t gpio);
+void gpio_set_dir(uint32_t gpio, uint32_t dir);
+void gpio_tlmm_config(uint32_t gpio,
+			uint8_t func,
+			uint8_t dir,
+			uint8_t pull,
+			uint8_t drvstr,
+			uint32_t enable);
+void gpio_set_value(uint32_t gpio, uint32_t value);
 #endif
diff --git a/platform/msm8916/include/platform/iomap.h b/platform/msm8916/include/platform/iomap.h
index 94fd16d..62eb8a8 100644
--- a/platform/msm8916/include/platform/iomap.h
+++ b/platform/msm8916/include/platform/iomap.h
@@ -29,12 +29,18 @@
 #ifndef _PLATFORM_MSM8916_IOMAP_H_
 #define _PLATFORM_MSM8916_IOMAP_H_
 
-#define MSM_IOMAP_BASE              0x0B000000
-#define MSM_IOMAP_END               0xBEFFFFF
+#define MSM_IOMAP_BASE              0x00100000
+#define MSM_IOMAP_END               0x00867FFF
 
+#define SYSTEM_IMEM_BASE            0x08600000
+#define MSM_SHARED_IMEM_BASE        0x08600000
+
+#define RESTART_REASON_ADDR         (MSM_SHARED_IMEM_BASE + 0x65C)
+#define BS_INFO_OFFSET              (0x6B0)
+#define BS_INFO_ADDR                (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET)
 #define SDRAM_START_ADDR            0x80000000
 
-#define MSM_SHARED_BASE             0x8E380000
+#define MSM_SHARED_BASE             0x8E200000
 
 #define APPS_SS_BASE                0x0B000000
 
@@ -47,70 +53,80 @@
 #define PERIPH_SS_BASE              0x07800000
 
 #define MSM_SDC1_BASE               (PERIPH_SS_BASE + 0x00024000)
+#define MSM_SDC1_SDHCI_BASE         (PERIPH_SS_BASE + 0x00024900)
 #define MSM_SDC2_BASE               (PERIPH_SS_BASE + 0x00064000)
+#define MSM_SDC2_SDHCI_BASE        (PERIPH_SS_BASE + 0x00064900)
 
+/* SDHCI */
+#define SDCC_MCI_HC_MODE            (0x00000078)
+#define SDCC_HC_PWRCTL_STATUS_REG   (0x000000DC)
+#define SDCC_HC_PWRCTL_MASK_REG     (0x000000E0)
+#define SDCC_HC_PWRCTL_CLEAR_REG    (0x000000E4)
+#define SDCC_HC_PWRCTL_CTL_REG      (0x000000E8)
 #define BLSP1_UART0_BASE            (PERIPH_SS_BASE + 0x000AF000)
 #define BLSP1_UART1_BASE            (PERIPH_SS_BASE + 0x000B0000)
 #define MSM_USB_BASE                (PERIPH_SS_BASE + 0x000D9000)
 
 #define CLK_CTL_BASE                0x1800000
 
-#define GCC_WDOG_DEBUG              (CLK_CTL_BASE +  0x00001780)
-
-#define USB_HS_BCR                  (CLK_CTL_BASE + 0x480)
-#define USB_BOOT_CLOCK_CTL          (CLK_CTL_BASE + 0x1A00)
-
-#define SPMI_BASE                   0xFC4C0000
+#define SPMI_BASE                   0x02000000
 #define SPMI_GENI_BASE              (SPMI_BASE + 0xA000)
-#define SPMI_PIC_BASE               (SPMI_BASE + 0xB000)
-
-#define MSM_CE1_BAM_BASE            0x00704000
-#define MSM_CE1_BASE                0x0073A000
+#define SPMI_PIC_BASE               (SPMI_BASE +  0x01800000)
 
 #define TLMM_BASE_ADDR              0x1000000
-#define GPIO_CONFIG_ADDR(x)         (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
-#define GPIO_IN_OUT_ADDR(x)         (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
+#define GPIO_CONFIG_ADDR(x)         (TLMM_BASE_ADDR + (x)*0x1000)
+#define GPIO_IN_OUT_ADDR(x)         (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000)
 
-#define MPM2_MPM_CTRL_BASE          0x004A1000
+#define MPM2_MPM_CTRL_BASE          0x004A0000
 #define MPM2_MPM_PS_HOLD            0x004AB0000
+#define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL  0x004A3000
 
-/* CE 2 */
-#define  GCC_CE2_BCR                (CLK_CTL_BASE + 0x1080)
-#define  GCC_CE2_CMD_RCGR           (CLK_CTL_BASE + 0x1090)
-#define  GCC_CE2_CFG_RCGR           (CLK_CTL_BASE + 0x1094)
-#define  GCC_CE2_CBCR               (CLK_CTL_BASE + 0x1084)
-#define  GCC_CE2_AXI_CBCR           (CLK_CTL_BASE + 0x1088)
-#define  GCC_CE2_AHB_CBCR           (CLK_CTL_BASE + 0x108C)
-
+/* CRYPTO ENGINER */
+#define  GCC_CRYPTO_BCR                (CLK_CTL_BASE + 0x16000)
+#define  GCC_CRYPTO_CMD_RCGR           (CLK_CTL_BASE + 0x16004)
+#define  GCC_CRYPTO_CFG_RCGR           (CLK_CTL_BASE + 0x16008)
+#define  GCC_CRYPTO_CBCR               (CLK_CTL_BASE + 0x1601C)
+#define  GCC_CRYPTO_AXI_CBCR           (CLK_CTL_BASE + 0x16020)
+#define  GCC_CRYPTO_AHB_CBCR           (CLK_CTL_BASE + 0x16024)
 /* GPLL */
-#define GPLL0_STATUS                (CLK_CTL_BASE + 0x001C)
-#define APCS_GPLL_ENA_VOTE          (CLK_CTL_BASE + 0x1480)
-#define APCS_CLOCK_BRANCH_ENA_VOTE  (CLK_CTL_BASE + 0x1484)
+#define GPLL0_STATUS                (CLK_CTL_BASE + 0x2101C)
+#define APCS_GPLL_ENA_VOTE          (CLK_CTL_BASE + 0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE  (CLK_CTL_BASE + 0x45004)
 
 /* SDCC */
-#define SDCC1_BCR                   (CLK_CTL_BASE + 0x4C0) /* block reset */
-#define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x4C4) /* branch control */
-#define SDCC1_AHB_CBCR              (CLK_CTL_BASE + 0x4C8)
-#define SDCC1_INACTIVITY_TIMER_CBCR (CLK_CTL_BASE + 0x4CC)
-#define SDCC1_CMD_RCGR              (CLK_CTL_BASE + 0x4D0) /* cmd */
-#define SDCC1_CFG_RCGR              (CLK_CTL_BASE + 0x4D4) /* cfg */
-#define SDCC1_M                     (CLK_CTL_BASE + 0x4D8) /* m */
-#define SDCC1_N                     (CLK_CTL_BASE + 0x4DC) /* n */
-#define SDCC1_D                     (CLK_CTL_BASE + 0x4E0) /* d */
+#define SDC1_HDRV_PULL_CTL          (TLMM_BASE_ADDR + 0x10A000)
+#define SDCC1_BCR                   (CLK_CTL_BASE + 0x42000) /* block reset*/
+#define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x42018) /* branch ontrol */
+#define SDCC1_AHB_CBCR              (CLK_CTL_BASE + 0x4201C)
+#define SDCC1_CMD_RCGR              (CLK_CTL_BASE + 0x42004) /* cmd */
+#define SDCC1_CFG_RCGR              (CLK_CTL_BASE + 0x42008) /* cfg */
+#define SDCC1_M                     (CLK_CTL_BASE + 0x4200C) /* m */
+#define SDCC1_N                     (CLK_CTL_BASE + 0x42010) /* n */
+#define SDCC1_D                     (CLK_CTL_BASE + 0x42014) /* d */
+
+#define SDCC2_BCR                   (CLK_CTL_BASE + 0x43000) /* block reset */
+#define SDCC2_APPS_CBCR             (CLK_CTL_BASE + 0x43018) /* branch control */
+#define SDCC2_AHB_CBCR              (CLK_CTL_BASE + 0x4301C)
+#define SDCC2_CMD_RCGR              (CLK_CTL_BASE + 0x43004) /* cmd */
+#define SDCC2_CFG_RCGR              (CLK_CTL_BASE + 0x43008) /* cfg */
+#define SDCC2_M                     (CLK_CTL_BASE + 0x4300C) /* m */
+#define SDCC2_N                     (CLK_CTL_BASE + 0x43010) /* n */
+#define SDCC2_D                     (CLK_CTL_BASE + 0x43014) /* d */
 
 /* UART */
-#define BLSP1_AHB_CBCR              (CLK_CTL_BASE + 0x5C4)
-#define BLSP1_UART2_APPS_CBCR       (CLK_CTL_BASE + 0x704)
-#define BLSP1_UART2_APPS_CMD_RCGR   (CLK_CTL_BASE + 0x70C)
-#define BLSP1_UART2_APPS_CFG_RCGR   (CLK_CTL_BASE + 0x710)
-#define BLSP1_UART2_APPS_M          (CLK_CTL_BASE + 0x714)
-#define BLSP1_UART2_APPS_N          (CLK_CTL_BASE + 0x718)
-#define BLSP1_UART2_APPS_D          (CLK_CTL_BASE + 0x71C)
+#define BLSP1_AHB_CBCR              (CLK_CTL_BASE + 0x1008)
+#define BLSP1_UART2_APPS_CBCR       (CLK_CTL_BASE + 0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR   (CLK_CTL_BASE + 0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR   (CLK_CTL_BASE + 0x3038)
+#define BLSP1_UART2_APPS_M          (CLK_CTL_BASE + 0x303C)
+#define BLSP1_UART2_APPS_N          (CLK_CTL_BASE + 0x3040)
+#define BLSP1_UART2_APPS_D          (CLK_CTL_BASE + 0x3044)
+
 
 /* USB */
-#define USB_HS_SYSTEM_CBCR          (CLK_CTL_BASE + 0x484)
-#define USB_HS_AHB_CBCR             (CLK_CTL_BASE + 0x488)
-#define USB_HS_SYSTEM_CMD_RCGR      (CLK_CTL_BASE + 0x490)
-#define USB_HS_SYSTEM_CFG_RCGR      (CLK_CTL_BASE + 0x494)
-
+#define USB_HS_BCR                  (CLK_CTL_BASE + 0x41000)
+#define USB_HS_SYSTEM_CBCR          (CLK_CTL_BASE + 0x41004)
+#define USB_HS_AHB_CBCR             (CLK_CTL_BASE + 0x41008)
+#define USB_HS_SYSTEM_CMD_RCGR      (CLK_CTL_BASE + 0x41010)
+#define USB_HS_SYSTEM_CFG_RCGR      (CLK_CTL_BASE + 0x41014)
 #endif
diff --git a/platform/msm8916/include/platform/irqs.h b/platform/msm8916/include/platform/irqs.h
index f371854..c3f6f8f 100644
--- a/platform/msm8916/include/platform/irqs.h
+++ b/platform/msm8916/include/platform/irqs.h
@@ -43,6 +43,8 @@
 #define INT_QTMR_VIRTUAL_TIMER_EXP             (GIC_PPI_START + 4)
 
 #define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP      (GIC_SPI_START + 8)
+#define SDCC1_PWRCTL_IRQ                       (GIC_SPI_START + 138)
+#define SDCC2_PWRCTL_IRQ                       (GIC_SPI_START + 221)
 
 #define USB1_HS_BAM_IRQ                        (GIC_SPI_START + 135)
 #define USB1_HS_IRQ                            (GIC_SPI_START + 134)
diff --git a/platform/msm8916/msm8916-clock.c b/platform/msm8916/msm8916-clock.c
new file mode 100644
index 0000000..ca4bd4c
--- /dev/null
+++ b/platform/msm8916/msm8916-clock.c
@@ -0,0 +1,328 @@
+/* Copyright (c) 2014, 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 <assert.h>
+#include <reg.h>
+#include <err.h>
+#include <clock.h>
+#include <clock_pll.h>
+#include <clock_lib2.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+
+
+/* Mux source select values */
+#define cxo_source_val    0
+#define gpll0_source_val  1
+struct clk_freq_tbl rcg_dummy_freq = F_END;
+
+
+/* Clock Operations */
+static struct clk_ops clk_ops_branch =
+{
+	.enable     = clock_lib2_branch_clk_enable,
+	.disable    = clock_lib2_branch_clk_disable,
+	.set_rate   = clock_lib2_branch_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg_mnd =
+{
+	.enable     = clock_lib2_rcg_enable,
+	.set_rate   = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg =
+{
+	.enable     = clock_lib2_rcg_enable,
+	.set_rate   = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_cxo =
+{
+	.enable     = cxo_clk_enable,
+	.disable    = cxo_clk_disable,
+};
+
+static struct clk_ops clk_ops_pll_vote =
+{
+	.enable     = pll_vote_clk_enable,
+	.disable    = pll_vote_clk_disable,
+	.auto_off   = pll_vote_clk_disable,
+	.is_enabled = pll_vote_clk_is_enabled,
+};
+
+static struct clk_ops clk_ops_vote =
+{
+	.enable     = clock_lib2_vote_clk_enable,
+	.disable    = clock_lib2_vote_clk_disable,
+};
+
+/* Clock Sources */
+static struct fixed_clk cxo_clk_src =
+{
+	.c = {
+		.rate     = 19200000,
+		.dbg_name = "cxo_clk_src",
+		.ops      = &clk_ops_cxo,
+	},
+};
+
+static struct pll_vote_clk gpll0_clk_src =
+{
+	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
+	.en_mask      = BIT(0),
+	.status_reg   = (void *) GPLL0_STATUS,
+	.status_mask  = BIT(17),
+	.parent       = &cxo_clk_src.c,
+
+	.c = {
+		.rate     = 800000000,
+		.dbg_name = "gpll0_clk_src",
+		.ops      = &clk_ops_pll_vote,
+	},
+};
+
+/* SDCC Clocks */
+static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] =
+{
+	F(   144000,    cxo,  16,   3,  25),
+	F(   400000,    cxo,  12,   1,   4),
+	F( 20000000,  gpll0,  10,   1,   4),
+	F( 25000000,  gpll0,  16,   1,   2),
+	F( 50000000,  gpll0,  16,   0,   0),
+	F(100000000,  gpll0,   8,   0,   0),
+	F(177770000,  gpll0, 4.5,   0,   0),
+	F(200000000,  gpll0,   4,   0,   0),
+	F_END
+};
+
+static struct rcg_clk sdcc1_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) SDCC1_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) SDCC1_CFG_RCGR,
+	.m_reg        = (uint32_t *) SDCC1_M,
+	.n_reg        = (uint32_t *) SDCC1_N,
+	.d_reg        = (uint32_t *) SDCC1_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_sdcc1_2_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "sdc1_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC1_APPS_CBCR,
+	.parent       = &sdcc1_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_sdcc1_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC1_AHB_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "gcc_sdcc1_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct rcg_clk sdcc2_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) SDCC2_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) SDCC2_CFG_RCGR,
+	.m_reg        = (uint32_t *) SDCC2_M,
+	.n_reg        = (uint32_t *) SDCC2_N,
+	.d_reg        = (uint32_t *) SDCC2_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_sdcc1_2_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "sdc2_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC2_APPS_CBCR,
+	.parent       = &sdcc2_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_sdcc2_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk =
+{
+	.cbcr_reg     = (uint32_t *) SDCC2_AHB_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "gcc_sdcc2_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+/* UART Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] =
+{
+	F( 3686400,  gpll0,    1,  72,  15625),
+	F( 7372800,  gpll0,    1, 144,  15625),
+	F(14745600,  gpll0,    1, 288,  15625),
+	F(16000000,  gpll0,   10,   1,      5),
+	F(19200000,    cxo,    1,   0,      0),
+	F(24000000,  gpll0,    1,   3,    100),
+	F(25000000,  gpll0,   16,   1,      2),
+	F(32000000,  gpll0,    1,   1,     25),
+	F(40000000,  gpll0,    1,   1,     20),
+	F(46400000,  gpll0,    1,  29,    500),
+	F(48000000,  gpll0,    1,   3,     50),
+	F(51200000,  gpll0,    1,   8,    125),
+	F(56000000,  gpll0,    1,   7,    100),
+	F(58982400,  gpll0,    1,1152,  15625),
+	F(60000000,  gpll0,    1,   3,     40),
+	F_END
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART2_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART2_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART2_APPS_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "blsp1_uart2_apps_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) BLSP1_UART2_APPS_CBCR,
+	.parent       = &blsp1_uart2_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) BLSP1_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(10),
+
+	.c = {
+		.dbg_name = "gcc_blsp1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+/* USB Clocks */
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] =
+{
+	F(80000000,  gpll0,   10,   0,   0),
+	F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src =
+{
+	.cmd_reg      = (uint32_t *) USB_HS_SYSTEM_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB_HS_SYSTEM_CFG_RCGR,
+
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_usb_hs_system_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb_hs_system_clk",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_usb_hs_system_clk =
+{
+	.cbcr_reg     = (uint32_t *) USB_HS_SYSTEM_CBCR,
+	.parent       = &usb_hs_system_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_usb_hs_system_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk =
+{
+	.cbcr_reg     = (uint32_t *) USB_HS_AHB_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "gcc_usb_hs_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+/* Clock lookup table */
+static struct clk_lookup msm_clocks_8916[] =
+{
+	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
+	CLK_LOOKUP("sdc1_core_clk",  gcc_sdcc1_apps_clk.c),
+
+	CLK_LOOKUP("sdc2_iface_clk", gcc_sdcc2_ahb_clk.c),
+	CLK_LOOKUP("sdc2_core_clk",  gcc_sdcc2_apps_clk.c),
+
+	CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("uart2_core_clk",  gcc_blsp1_uart2_apps_clk.c),
+
+	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
+	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
+};
+
+void platform_clock_init(void)
+{
+	clk_init(msm_clocks_8916, ARRAY_SIZE(msm_clocks_8916));
+}
diff --git a/platform/msm8916/platform.c b/platform/msm8916/platform.c
index 8aaef9c..bab48ef 100644
--- a/platform/msm8916/platform.c
+++ b/platform/msm8916/platform.c
@@ -31,9 +31,36 @@
 #include <platform/iomap.h>
 #include <qgic.h>
 #include <qtimer.h>
+#include <mmu.h>
+#include <arch/arm/mmu.h>
+#include <smem.h>
+#include <board.h>
+#include <boot_stats.h>
+
+#define MB (1024*1024)
+
+#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
+
+/* LK memory - cacheable, write through */
+#define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+					MMU_MEMORY_AP_READ_WRITE)
+
+/* Peripherals - non-shared device */
+#define IOMAP_MEMORY      (MMU_MEMORY_TYPE_DEVICE_SHARED | \
+			MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+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},
+};
+
+static struct smem_ram_ptable ram_ptable;
 
 void platform_early_init(void)
 {
+	board_init();
+	platform_clock_init();
 	qgic_init();
 	qtimer_init();
 }
@@ -47,3 +74,70 @@
 {
 	qtimer_uninit();
 }
+
+uint32_t platform_get_sclk_count(void)
+{
+	return readl(MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL);
+}
+
+addr_t get_bs_info_addr()
+{
+	return ((addr_t)BS_INFO_ADDR);
+}
+
+/* Setup memory for this platform */
+void platform_init_mmu_mappings(void)
+{
+	uint32_t i;
+	uint32_t sections;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	ram_partition ptn_entry;
+	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_THROUGH | \
+										 MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN));
+				}
+			}
+		}
+	}
+
+	/* Configure the MMU page entries for memory read from the
+	   mmu_section_table */
+	for (i = 0; i < table_size; i++)
+	{
+		sections = mmu_section_table[i].num_of_sections;
+
+		while (sections--)
+		{
+			arm_mmu_map_section(mmu_section_table[i].paddress +
+								sections * MB,
+								mmu_section_table[i].vaddress +
+								sections * MB,
+								mmu_section_table[i].flags);
+		}
+	}
+}
diff --git a/platform/msm8916/rules.mk b/platform/msm8916/rules.mk
index e30edd3..85dff4f 100644
--- a/platform/msm8916/rules.mk
+++ b/platform/msm8916/rules.mk
@@ -18,6 +18,7 @@
 OBJS += \
        $(LOCAL_DIR)/platform.o \
        $(LOCAL_DIR)/acpuclock.o \
+       $(LOCAL_DIR)/msm8916-clock.o \
        $(LOCAL_DIR)/gpio.o
 
 LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index 5ea74c4..abbe64d 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.h
@@ -148,6 +148,7 @@
 #define MMC_CLK_48MHZ                             48000000
 #define MMC_CLK_50MHZ                             49152000
 #define MMC_CLK_96MHZ                             96000000
+#define MMC_CLK_177MHZ                            177770000
 #define MMC_CLK_200MHZ                            200000000
 #define MMC_CLK_192MHZ                            192000000
 #define MMC_CLK_400MHZ                            400000000
diff --git a/platform/msm_shared/include/spmi_v2.h b/platform/msm_shared/include/spmi_v2.h
new file mode 100644
index 0000000..d70fa1c
--- /dev/null
+++ b/platform/msm_shared/include/spmi_v2.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2014, 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 __SPMI_H
+#define __SPMI_H
+
+#define SPMI_GENI_REG(x)                     (SPMI_GENI_BASE + (x))
+#define SPMI_GENI_CFG_REG_BASE               SPMI_GENI_REG(0x100)
+#define SPMI_GENI_CFG_RAM_BASE               SPMI_GENI_REG(0x200)
+
+#define SPMI_GENI_CFG_REGn(x)                (SPMI_GENI_CFG_REG_BASE + 4 * (x))
+#define SPMI_GENI_CFG_RAM_REGn(x)            (SPMI_GENI_CFG_RAM_BASE + 4 * (x))
+
+#define SPMI_GENI_CLK_CTRL_REG               SPMI_GENI_REG(0x00)
+#define SPMI_GENI_OUTPUT_CTRL_REG            SPMI_GENI_REG(0x14)
+#define SPMI_GENI_FORCE_DEFAULT_REG          SPMI_GENI_REG(0x10)
+#define SPMI_MID_REG                         SPMI_GENI_REG(0xF00)
+#define SPMI_CFG_REG                         SPMI_GENI_REG(0xF04)
+#define SPMI_SEC_DISABLE_REG                 SPMI_GENI_REG(0xF08)
+
+#define PMIC_ARB_CORE_REG_BASE               (SPMI_BASE + 0x00400000)
+#define PMIC_ARB_CHNLn_CONFIG(x)             (PMIC_ARB_CORE_REG_BASE + 0x00000004 + (x) * 0x8000)
+#define PMIC_ARB_CHNLn_STATUS(x)             (PMIC_ARB_CORE_REG_BASE + 0x00000008 + (x) * 0x8000)
+#define PMIC_ARB_CHNLn_WDATA(x, n)           (PMIC_ARB_CORE_REG_BASE + 0x00000010 + (x) * 0x8000 + (n) * 4)
+#define PMIC_ARB_CHNLn_RDATA(x,n)            (PMIC_ARB_CORE_REG_BASE + 0x00000018 + (x) * 0x8000 + (n) * 4)
+
+#define PMIC_ARB_CHNLn_CMD0(x)               (PMIC_ARB_CORE_REG_BASE + (x) * 0x8000)
+#define PMIC_ARB_CMD_OPCODE_SHIFT            27
+#define PMIC_ARB_CMD_PRIORITY_SHIFT          26
+#define PMIC_ARB_CMD_SLAVE_ID_SHIFT          20
+#define PMIC_ARB_CMD_ADDR_SHIFT              12
+#define PMIC_ARB_CMD_ADDR_OFFSET_SHIFT       4
+#define PMIC_ARB_CMD_BYTE_CNT_SHIFT          0
+
+/* PIC Registers */
+#define SPMI_PIC_OWNERm_ACC_STATUSn(m, n)    (SPMI_PIC_BASE + 0x00100000 + 0x1000 * (m) + 0x4 * (n))
+#define SPMI_PIC_ACC_ENABLEn(n)              (SPMI_PIC_BASE + 0x1000 * n )
+#define SPMI_PIC_IRQ_STATUSn(n)              (SPMI_PIC_BASE + 0x00000004 + 0x1000 * (n))
+#define SPMI_PIC_IRQ_CLEARn(n)               (SPMI_PIC_BASE + 0x00000008 + 0x1000 * (n))
+
+/* SPMI Commands */
+#define SPMI_CMD_EXT_REG_WRTIE_LONG          0x00
+#define SPMI_CMD_EXT_REG_READ_LONG           0x01
+#define SPMI_CMD_EXT_REG_READ_LONG_DELAYED   0x02
+#define SPMI_CMD_TRANSFER_BUS_OWNERSHIP      0x03
+
+/* The commands below are not yet supported */
+#define SPMI_CMD_RESET                       0x04
+#define SPMI_CMD_SLEEP                       0x05
+#define SPMI_CMD_SHUTDOWN                    0x06
+#define SPMI_CMD_WAKEUP                      0x07
+#define SPMI_CMD_EXT_REG_WRITE               0x08
+#define SPMI_CMD_EXT_REG_READ                0x09
+#define SPMI_CMD_REG_WRITE                   0x0A
+#define SPMI_CMD_REG_READ                    0x0B
+#define SPMI_CMD_REG_0_WRITE                 0x0C
+#define SPMI_CMD_AUTH                        0x0D
+#define SPMI_CMD_MASTER_WRITE                0x0E
+#define SPMI_CMD_MASTER_READ                 0x0F
+#define SPMI_CMD_DEV_DESC_BLK_MASTER_READ    0x10
+#define SPMI_CMD_DEV_DESC_BLK_SLAVE_READ     0x11
+
+enum spmi_geni_cmd_return_value{
+	SPMI_CMD_DONE,
+	SMPI_CMD_DENIED,
+	SPMI_CMD_FAILURE,
+	SPMI_ILLEGAL_CMD,
+	SPMI_CMD_OVERRUN = 6,
+	SPMI_TX_FIFO_RD_ERR,
+	SPMI_TX_FIFO_WR_ERR,
+	SPMI_RX_FIFO_RD_ERR,
+	SPMI_RX_FIFO_WR_ERR
+};
+
+enum pmic_arb_chnl_return_values{
+	PMIC_ARB_CMD_DONE,
+	PMIC_ARB_CMD_FAILURE,
+	PMIC_ARB_CMD_DENIED,
+	PMIC_ARB_CMD_DROPPED,
+};
+
+struct pmic_arb_cmd{
+	uint8_t opcode;
+	uint8_t priority;
+	uint8_t slave_id;
+	uint8_t address;
+	uint8_t offset;
+	uint8_t byte_cnt;
+};
+
+struct pmic_arb_param{
+	uint8_t *buffer;
+	uint8_t size;
+};
+
+typedef void (*spmi_callback)();
+
+void spmi_init(uint32_t, uint32_t);
+unsigned int pmic_arb_write_cmd(struct pmic_arb_cmd *cmd,
+	struct pmic_arb_param *param);
+unsigned int pmic_arb_read_cmd(struct pmic_arb_cmd *cmd,
+	struct pmic_arb_param *param);
+
+#endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index a022e04..78edf48 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -166,6 +166,7 @@
 		$(LOCAL_DIR)/spmi.o \
 		$(LOCAL_DIR)/bam.o \
 		$(LOCAL_DIR)/qpic_nand.o \
+		$(LOCAL_DIR)/gpio.o \
 		$(LOCAL_DIR)/dev_tree.o
 endif
 
diff --git a/platform/msm_shared/spmi.c b/platform/msm_shared/spmi.c
index 6023213..4d48705 100644
--- a/platform/msm_shared/spmi.c
+++ b/platform/msm_shared/spmi.c
@@ -28,7 +28,11 @@
 
 #include <debug.h>
 #include <reg.h>
+#if SPMI_CORE_V2
+#include <spmi_v2.h>
+#else
 #include <spmi.h>
+#endif
 #include <platform/iomap.h>
 #include <platform/irqs.h>
 #include <platform/interrupts.h>
diff --git a/project/msm8916.mk b/project/msm8916.mk
index 76a1a50..806082b 100644
--- a/project/msm8916.mk
+++ b/project/msm8916.mk
@@ -23,3 +23,9 @@
 
 #Disable thumb mode
 ENABLE_THUMB := false
+
+ENABLE_SDHCI_SUPPORT := 1
+
+ifeq ($(ENABLE_SDHCI_SUPPORT),1)
+DEFINES += MMC_SDHCI_SUPPORT=1
+endif
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index 68865bb..a334b93 100644
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -243,6 +243,7 @@
 	config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
 	config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
 	config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 1;
 
 	if (!(dev = mmc_init(&config)))
 	{
diff --git a/target/mpq8092/init.c b/target/mpq8092/init.c
index 997a599..4e98f03 100644
--- a/target/mpq8092/init.c
+++ b/target/mpq8092/init.c
@@ -119,6 +119,7 @@
 	config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
 	config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
 	config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 1;
 
 	if (!(dev = mmc_init(&config))) {
 		/* Try slot 2 */
diff --git a/target/msm8226/init.c b/target/msm8226/init.c
index 8be3b2f..71b46c5 100644
--- a/target/msm8226/init.c
+++ b/target/msm8226/init.c
@@ -216,6 +216,7 @@
 	config.sdhc_base = mmc_sdhci_base[config.slot - 1];
 	config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
 	config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 0;
 
 	if (!(dev = mmc_init(&config)))
 	{
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index 285b866..2ab3bc7 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -33,30 +33,110 @@
 #include <platform.h>
 #include <uart_dm.h>
 #include <mmc.h>
-#include <spmi.h>
+#include <platform/gpio.h>
+#include <dev/keys.h>
+#include <spmi_v2.h>
+#include <pm8x41.h>
 #include <board.h>
+#include <baseband.h>
+#include <hsusb.h>
+#include <platform/gpio.h>
+#include <platform/gpio.h>
+#include <platform/irqs.h>
 
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
+#define TLMM_VOL_UP_BTN_GPIO    107
 
-static uint32_t mmc_sdc_base[] =
+static void set_sdc_power_ctrl(void);
+
+struct mmc_device *dev;
+
+static uint32_t mmc_pwrctl_base[] =
 	{ MSM_SDC1_BASE, MSM_SDC2_BASE };
 
+static uint32_t mmc_sdhci_base[] =
+        { MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
+
+static uint32_t  mmc_sdc_pwrctl_irq[] =
+        { SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
+
 void target_early_init(void)
 {
 #if WITH_DEBUG_UART
-	uart_dm_init(1, 0, BLSP1_UART1_BASE);
+	uart_dm_init(2, 0, BLSP1_UART1_BASE);
 #endif
 }
-void target_mmc_caps(struct mmc_host *host)
+
+void target_sdc_init()
 {
-	host->caps.ddr_mode = 0;
-	host->caps.hs200_mode = 0;
-	host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
-	host->caps.hs_clk_rate = MMC_CLK_50MHZ;
+	struct mmc_config_data config;
+
+	/* Set drive strength & pull ctrl values */
+	set_sdc_power_ctrl();
+
+	config.bus_width = DATA_BUS_WIDTH_8BIT;
+	config.max_clk_rate = MMC_CLK_200MHZ;
+
+	/* Try slot 1*/
+	config.slot         = 1;
+	config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
+	config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
+	config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 0;
+
+	if (!(dev = mmc_init(&config))) {
+	/* Try slot 2 */
+		config.slot         = 2;
+		config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
+		config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
+		config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
+
+		if (!(dev = mmc_init(&config))) {
+			dprintf(CRITICAL, "mmc init failed!");
+			ASSERT(0);
+		}
+	}
 }
+
+void *target_mmc_device()
+{
+	return (void *) dev;
+}
+
+/* Return 1 if vol_up pressed */
+static int target_volume_up()
+{
+	uint8_t status = 0;
+
+	gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+
+	/* Wait for the gpio config to take effect - debounce time */
+	thread_sleep(10);
+
+	/* Get status of GPIO */
+	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
+
+	/* Active low signal. */
+	return !status;
+}
+
+/* Return 1 if vol_down pressed */
+uint32_t target_volume_down()
+{
+	/* Volume down button tied in with PMIC RESIN. */
+	return pm8x41_resin_status();
+}
+
 static void target_keystatus()
 {
+	keys_init();
+
+	if(target_volume_down())
+		keys_post_event(KEY_VOLUMEDOWN, 1);
+
+	if(target_volume_up())
+		keys_post_event(KEY_VOLUMEUP, 1);
 }
 
 void target_init(void)
@@ -69,21 +149,14 @@
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
 
 	target_keystatus();
+	set_sdc_power_ctrl();
 
-	/* Trying Slot 1*/
-	slot = 1;
-	base_addr = mmc_sdc_base[slot - 1];
-	if (mmc_boot_main(slot, base_addr))
+	target_sdc_init();
+	if (partition_read_table())
 	{
-
-	/* Trying Slot 2 next */
-	slot = 2;
-	base_addr = mmc_sdc_base[slot - 1];
-	if (mmc_boot_main(slot, base_addr)) {
-		dprintf(CRITICAL, "mmc init failed!");
+		dprintf(CRITICAL, "Error reading the partition table info\n");
 		ASSERT(0);
 	}
-	}
 }
 
 void target_serialno(unsigned char *buf)
@@ -97,4 +170,125 @@
 
 unsigned board_machtype(void)
 {
+	return LINUX_MACHTYPE_UNKNOWN;
+}
+
+unsigned check_reboot_mode(void)
+{
+	uint32_t restart_reason = 0;
+
+	/* Read reboot reason and scrub it */
+	restart_reason = readl(RESTART_REASON_ADDR);
+	writel(0x00, RESTART_REASON_ADDR);
+
+	return restart_reason;
+}
+
+void reboot_device(unsigned reboot_reason)
+{
+	writel(reboot_reason, RESTART_REASON_ADDR);
+
+	/* Configure PMIC for warm reset */
+	pm8x41_reset_configure(PON_PSHOLD_WARM_RESET);
+
+	/* Drop PS_HOLD for MSM */
+	writel(0x00, MPM2_MPM_PS_HOLD);
+
+	mdelay(5000);
+
+	dprintf(CRITICAL, "Rebooting failed\n");
+}
+
+/* Detect the target type */
+void target_detect(struct board_data *board)
+{
+	/*
+	* already fill the board->target on board.c
+	*/
+}
+
+void target_baseband_detect(struct board_data *board)
+{
+	uint32_t platform;
+
+	platform = board->platform;
+	switch(platform)
+	{
+	case MSM8916:
+		board->baseband = BASEBAND_MSM;
+	break;
+	default:
+		dprintf(CRITICAL, "Platform type: %u is not supported\n", platform);
+	ASSERT(0);
+	};
+}
+
+unsigned target_baseband()
+{
+	return board_baseband();
+}
+
+int emmc_recovery_init(void)
+{
+	return _emmc_recovery_init();
+}
+
+static void set_sdc_power_ctrl()
+{
+	/* Drive strength configs for sdc pins */
+	struct tlmm_cfgs sdc1_hdrv_cfg[] =
+	{
+		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK },
+		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
+		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_6MA, TLMM_HDRV_MASK },
+	};
+
+	/* Pull configs for sdc pins */
+	struct tlmm_cfgs sdc1_pull_cfg[] =
+	{
+		{ SDC1_CLK_PULL_CTL_OFF,  TLMM_NO_PULL, TLMM_PULL_MASK },
+		{ SDC1_CMD_PULL_CTL_OFF,  TLMM_PULL_UP, TLMM_PULL_MASK },
+		{ SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
+	};
+
+	/* Set the drive strength & pull control values */
+	tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
+	tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
+}
+
+void target_usb_init(void)
+{
+	uint32_t val;
+
+	/* Select and enable external configuration with USB PHY */
+	ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
+
+	/* Enable sess_vld */
+	val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
+	writel(val, USB_GENCONFIG_2);
+
+	/* Enable external vbus configuration in the LINK */
+	val = readl(USB_USBCMD);
+	val |= SESS_VLD_CTRL;
+	writel(val, USB_USBCMD);
+}
+
+void target_usb_stop(void)
+{
+	/* Disable VBUS mimicing in the controller. */
+	ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_CLEAR);
+}
+
+
+void target_uninit(void)
+{
+	mmc_put_card_to_sleep(dev);
+	sdhci_mode_disable(&dev->host);
+}
+
+/* Do any target specific intialization needed before entering fastboot mode */
+void target_fastboot_init(void)
+{
+	/* Set the BOOT_DONE flag in PM8916 */
+	pm8x41_set_boot_done();
 }
diff --git a/target/msm8916/meminfo.c b/target/msm8916/meminfo.c
index 708cde3..9d76bf6 100644
--- a/target/msm8916/meminfo.c
+++ b/target/msm8916/meminfo.c
@@ -35,37 +35,42 @@
 #include <platform/iomap.h>
 #include <dev_tree.h>
 
-/* Funtion to add the ram partition entries into device tree.
- * The function assumes that all the entire fixed memory regions should
- * be listed in the first bank of the passed in ddr regions.
- */
 uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
 {
-	struct smem_ram_ptable ram_ptable;
-	uint32_t i;
+	ram_partition ptn_entry;
+	unsigned int index;
 	int ret = 0;
+	uint32_t len = 0;
 
 	/* Make sure RAM partition table is initialized */
-	ASSERT(smem_ram_ptable_init(&ram_ptable));
+	ASSERT(smem_ram_ptable_init_v1());
+
+	len = smem_get_ram_ptable_len();
 
 	/* Calculating the size of the mem_info_ptr */
-	for (i = 0 ; i < ram_ptable.len; i++)
+	for (index = 0 ; index < len; index++)
 	{
-		if ((ram_ptable.parts[i].category == SDRAM) &&
-			(ram_ptable.parts[i].type == SYS_MEMORY)) {
+		smem_get_ram_ptable_entry(&ptn_entry, index);
+
+		if((ptn_entry.category == SDRAM) &&
+			(ptn_entry.type == SYS_MEMORY))
+		{
 
 			/* Pass along all other usable memory regions to Linux */
 			ret = dev_tree_add_mem_info(fdt,
-					memory_node_offset,
-					ram_ptable.parts[i].start,
-					ram_ptable.parts[i].size);
-			if (ret) {
+							memory_node_offset,
+							ptn_entry.start,
+							ptn_entry.size);
+
+			if (ret)
+			{
 				dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
 				goto target_dev_tree_mem_err;
 			}
 		}
 	}
 target_dev_tree_mem_err:
+
 	return ret;
 }