Merge "platform: msm_shared: Update clock & usb phy driver"
diff --git a/include/platform.h b/include/platform.h
index 7a162f4..156097e 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -66,6 +66,7 @@
 int platform_is_msm8909();
 int platform_is_msm8992();
 int platform_is_msm8956();
+uint32_t platform_is_msm8976_v_1_1();
 int boot_device_mask(int);
 uint32_t platform_detect_panel();
 uint32_t platform_get_max_periph();
diff --git a/platform/mdmfermium/acpuclock.c b/platform/mdmfermium/acpuclock.c
index 7463222..bd068ad 100644
--- a/platform/mdmfermium/acpuclock.c
+++ b/platform/mdmfermium/acpuclock.c
@@ -37,11 +37,81 @@
 
 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", 133330000, 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);
+	}
 }
 
 /* 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);
+
+	ret = clk_get_set_enable(iclk, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
+		ASSERT(0);
+	}
+
+	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/mdmfermium/include/platform/iomap.h b/platform/mdmfermium/include/platform/iomap.h
index d1eb89e..205cd19 100644
--- a/platform/mdmfermium/include/platform/iomap.h
+++ b/platform/mdmfermium/include/platform/iomap.h
@@ -88,18 +88,18 @@
 
 
 /* GPLL */
-#define GPLL0_STATUS                       (CLK_CTL_BASE + 0x21024)
+#define GPLL0_MODE                         (CLK_CTL_BASE + 0x21000)
 #define APCS_GPLL_ENA_VOTE                 (CLK_CTL_BASE + 0x45000)
 #define APCS_CLOCK_BRANCH_ENA_VOTE         (CLK_CTL_BASE + 0x45004)
 
 /* UART */
 #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)
+#define BLSP1_UART5_APPS_CBCR              (CLK_CTL_BASE + 0x603c)
+#define BLSP1_UART5_APPS_CMD_RCGR          (CLK_CTL_BASE + 0x6044)
+#define BLSP1_UART5_APPS_CFG_RCGR          (CLK_CTL_BASE + 0x6048)
+#define BLSP1_UART5_APPS_M                 (CLK_CTL_BASE + 0x604C)
+#define BLSP1_UART5_APPS_N                 (CLK_CTL_BASE + 0x6050)
+#define BLSP1_UART5_APPS_D                 (CLK_CTL_BASE + 0x6054)
 
 /* USB */
 #define USB_HS_BCR                         (CLK_CTL_BASE + 0x41000)
diff --git a/platform/mdmfermium/mdmfermium-clock.c b/platform/mdmfermium/mdmfermium-clock.c
index 235d40f..35fbd27 100644
--- a/platform/mdmfermium/mdmfermium-clock.c
+++ b/platform/mdmfermium/mdmfermium-clock.c
@@ -100,8 +100,8 @@
 {
 	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
 	.en_mask      = BIT(0),
-	.status_reg   = (void *) GPLL0_STATUS,
-	.status_mask  = BIT(17),
+	.status_reg   = (void *) GPLL0_MODE,
+	.status_mask  = BIT(30),
 	.parent       = &cxo_clk_src.c,
 
 	.c = {
@@ -112,7 +112,7 @@
 };
 
 /* UART Clocks */
-static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_2_apps_clk[] =
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart5_apps_clk[] =
 {
 	F( 3686400,  gpll0,    1,  72,  15625),
 	F( 7372800,  gpll0,    1, 144,  15625),
@@ -132,16 +132,16 @@
 	F_END
 };
 
-static struct rcg_clk blsp1_uart2_apps_clk_src =
+static struct rcg_clk blsp1_uart5_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,
+	.cmd_reg      = (uint32_t *) BLSP1_UART5_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART5_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART5_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART5_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART5_APPS_D,
 
 	.set_rate     = clock_lib2_rcg_set_rate_mnd,
-	.freq_tbl     = ftbl_gcc_blsp1_2_uart1_2_apps_clk,
+	.freq_tbl     = ftbl_gcc_blsp1_2_uart5_apps_clk,
 	.current_freq = &rcg_dummy_freq,
 
 	.c = {
@@ -150,13 +150,13 @@
 	},
 };
 
-static struct branch_clk gcc_blsp1_uart2_apps_clk =
+static struct branch_clk gcc_blsp1_uart5_apps_clk =
 {
-	.cbcr_reg     = (uint32_t *) BLSP1_UART2_APPS_CBCR,
-	.parent       = &blsp1_uart2_apps_clk_src.c,
+	.cbcr_reg     = (uint32_t *) BLSP1_UART5_APPS_CBCR,
+	.parent       = &blsp1_uart5_apps_clk_src.c,
 
 	.c = {
-		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.dbg_name = "gcc_blsp1_uart5_apps_clk",
 		.ops      = &clk_ops_branch,
 	},
 };
@@ -219,8 +219,8 @@
 /* Clock lookup table */
 static struct clk_lookup mdm_clocks_fermium[] =
 {
-	CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
-	CLK_LOOKUP("uart2_core_clk",  gcc_blsp1_uart2_apps_clk.c),
+	CLK_LOOKUP("uart5_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("uart5_core_clk",  gcc_blsp1_uart5_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),
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
index e3aaec3..4cf5813 100644
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -132,7 +132,12 @@
 	}
 	else if(freq == MMC_CLK_192MHZ)
 	{
-		ret = clk_get_set_enable(clk_name, 192000000, 1);
+		if (platform_is_msm8956() && platform_is_msm8976_v_1_1())
+
+			ret = clk_get_set_enable(clk_name, 186400000, 1);
+		else
+
+			ret = clk_get_set_enable(clk_name, 192000000, 1);
 	}
 	else if(freq == MMC_CLK_200MHZ)
 	{
@@ -140,7 +145,12 @@
 	}
 	else if(freq == MMC_CLK_400MHZ)
 	{
-		ret = clk_get_set_enable(clk_name, 384000000, 1);
+		if (platform_is_msm8956() && platform_is_msm8976_v_1_1())
+
+			ret = clk_get_set_enable(clk_name, 372800000, 1);
+		else
+
+			ret = clk_get_set_enable(clk_name, 384000000, 1);
 	}
 	else
 	{
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index 6a568db..2bf5d7e 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -98,6 +98,7 @@
 
 /* GPLL */
 #define GPLL0_STATUS                       (CLK_CTL_BASE + 0x2101C)
+#define GPLL2_STATUS                       (CLK_CTL_BASE + 0x4A01C)
 #define APCS_GPLL_ENA_VOTE                 (CLK_CTL_BASE + 0x45000)
 #define APCS_CLOCK_BRANCH_ENA_VOTE         (CLK_CTL_BASE + 0x45004)
 #define GPLL4_MODE                         (CLK_CTL_BASE + 0x24000)
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
index b87406d..3214895 100644
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -39,6 +39,7 @@
 /* Mux source select values */
 #define cxo_source_val    0
 #define gpll0_source_val  1
+#define gpll2_source_val  4
 #define gpll4_source_val  2
 #define cxo_mm_source_val 0
 #define gpll0_mm_source_val 6
@@ -112,6 +113,21 @@
 	},
 };
 
+static struct pll_vote_clk gpll2_clk_src =
+{
+	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
+	.en_mask      = BIT(2),
+	.status_reg   = (void *) GPLL2_STATUS,
+	.status_mask  = BIT(17),
+	.parent       = &cxo_clk_src.c,
+
+	.c = {
+		.rate     = 932000000,
+		.dbg_name = "gpll2_clk_src",
+		.ops      = &clk_ops_pll_vote,
+	},
+};
+
 static struct pll_vote_clk gpll4_clk_src =
 {
 	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
@@ -157,6 +173,21 @@
 	F_END
 };
 
+/* SDCC Clocks for version 8976 v 1.1*/
+static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk_8976_v_1_1[] =
+{
+	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(186400000,  gpll2,   5,   0,   0),
+	F(372800000,  gpll2, 2.5,   0,   0),
+	F_END
+};
+
 static struct rcg_clk sdcc1_apps_clk_src =
 {
 	.cmd_reg      = (uint32_t *) SDCC1_CMD_RCGR,
@@ -594,9 +625,18 @@
 	mdss_mdp_clk_src.freq_tbl = ftbl_mdp_clk_8956;
 }
 
+void msm8976_v_1_1_sdcc_clock_modify()
+{
+	sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_8976_v_1_1;
+}
+
 void platform_clock_init(void)
 {
-	if (platform_is_msm8956())
+	if (platform_is_msm8956()) {
 		msm8956_clock_override();
+		if (platform_is_msm8976_v_1_1())
+			/*freq and GPLL change for 8976 v1.1 */
+			msm8976_v_1_1_sdcc_clock_modify();
+	}
 	clk_init(msm_clocks_8952, ARRAY_SIZE(msm_clocks_8952));
 }
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
index ec5a1d8..8adaf4c 100644
--- a/platform/msm8952/platform.c
+++ b/platform/msm8952/platform.c
@@ -41,6 +41,7 @@
 #include <platform.h>
 #include <target/display.h>
 
+#define MSM8976_SOC_V11 0x10001
 #define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
 #define APPS_SS_SIZE   ((APPS_SS_END - APPS_SS_BASE)/MB)
 
@@ -194,3 +195,14 @@
 
 	return ret;
 }
+
+uint32_t platform_is_msm8976_v_1_1()
+{
+	uint32_t soc_ver = board_soc_version();
+	uint32_t ret = 0;
+
+	if(soc_ver == MSM8976_SOC_V11)
+		ret = 1;
+
+	return ret;
+}
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 7abfbc9..312a33d 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -435,7 +435,11 @@
 	MDMCALIFORNIUM4  = 285,
 	MDMCALIFORNIUM5  = 286,
 	APQ8052  = 289,
-	MDMFERMIUM  = 290,
+	MDMFERMIUM1 = 290,
+	MDMFERMIUM2  = 296,
+	MDMFERMIUM3  = 297,
+	MDMFERMIUM4  = 298,
+	MDMFERMIUM5  = 299,
 	APQ8096  = 291,
 	MSMTITANIUM  = 293,
 };
diff --git a/project/mdmfermium.mk b/project/mdmfermium.mk
index 8a7b5f5..96de0cb 100644
--- a/project/mdmfermium.mk
+++ b/project/mdmfermium.mk
@@ -17,6 +17,7 @@
 DEFINES += DEVICE_TREE=1
 DEFINES += CONTIGUOUS_MEMORY=1
 
+DEFINES += SPMI_CORE_V2=1
 DEFINES += BAM_V170=1
 #Disable thumb mode
 ENABLE_THUMB := false
diff --git a/target/mdmfermium/init.c b/target/mdmfermium/init.c
index 65d1b0a..3bfb3c0 100644
--- a/target/mdmfermium/init.c
+++ b/target/mdmfermium/init.c
@@ -118,7 +118,8 @@
 void target_early_init(void)
 {
 #if WITH_DEBUG_UART
-	uart_dm_init(1, 0, BLSP1_UART5_BASE);
+	/*BLSP1 and UART5*/
+	uart_dm_init(5, 0, BLSP1_UART5_BASE);
 #endif
 }
 
@@ -190,7 +191,11 @@
 
 	switch(platform)
 	{
-	case MDMFERMIUM:
+	case MDMFERMIUM1:
+	case MDMFERMIUM2:
+	case MDMFERMIUM3:
+	case MDMFERMIUM4:
+	case MDMFERMIUM5:
 		board->baseband = BASEBAND_MDM;
         break;
 	default: