Merge "platform: msm8994: Add sdc2 support"
diff --git a/platform/msm8994/acpuclock.c b/platform/msm8994/acpuclock.c
index cd990f2..ba316fa 100644
--- a/platform/msm8994/acpuclock.c
+++ b/platform/msm8994/acpuclock.c
@@ -142,6 +142,10 @@
 	{
 		ret = clk_get_set_enable(clk_name, 192000000, 1);
 	}
+	else if(freq == MMC_CLK_200MHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 200000000, 1);
+	}
 	else if(freq == MMC_CLK_400MHZ)
 	{
 		ret = clk_get_set_enable(clk_name, 384000000, 1);
diff --git a/platform/msm8994/include/platform/iomap.h b/platform/msm8994/include/platform/iomap.h
index aade4bd..7a10fbc 100644
--- a/platform/msm8994/include/platform/iomap.h
+++ b/platform/msm8994/include/platform/iomap.h
@@ -162,6 +162,17 @@
 #define SDCC1_N                     (CLK_CTL_BASE + 0x4DC) /* n */
 #define SDCC1_D                     (CLK_CTL_BASE + 0x4E0) /* d */
 
+/* SDCC2 */
+#define SDCC2_BCR                   (CLK_CTL_BASE + 0x500) /* block reset */
+#define SDCC2_APPS_CBCR             (CLK_CTL_BASE + 0x504) /* branch control */
+#define SDCC2_AHB_CBCR              (CLK_CTL_BASE + 0x508)
+#define SDCC2_INACTIVITY_TIMER_CBCR (CLK_CTL_BASE + 0x50C)
+#define SDCC2_CMD_RCGR              (CLK_CTL_BASE + 0x510) /* cmd */
+#define SDCC2_CFG_RCGR              (CLK_CTL_BASE + 0x514) /* cfg */
+#define SDCC2_M                     (CLK_CTL_BASE + 0x518) /* m */
+#define SDCC2_N                     (CLK_CTL_BASE + 0x51C) /* n */
+#define SDCC2_D                     (CLK_CTL_BASE + 0x520) /* d */
+
 /* SDCC3 */
 #define SDCC3_BCR                   (CLK_CTL_BASE + 0x540) /* block reset */
 #define SDCC3_APPS_CBCR             (CLK_CTL_BASE + 0x544) /* branch control */
@@ -195,6 +206,7 @@
 
 /* DRV strength for sdcc */
 #define SDC1_HDRV_PULL_CTL           (TLMM_BASE_ADDR + 0x00002044)
+#define SDC2_HDRV_PULL_CTL           (TLMM_BASE_ADDR + 0x00002048)
 
 /* SDHCI */
 #define SDCC_MCI_HC_MODE            (0x00000078)
diff --git a/platform/msm8994/msm8994-clock.c b/platform/msm8994/msm8994-clock.c
index 033a88d..2c42f41 100644
--- a/platform/msm8994/msm8994-clock.c
+++ b/platform/msm8994/msm8994-clock.c
@@ -283,7 +283,7 @@
 };
 
 /* SDCC Clocks */
-static struct clk_freq_tbl ftbl_gcc_sdcc1_4_apps_clk[] =
+static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk[] =
 {
 	F(   144000,    cxo,  16,   3,  25),
 	F(   400000,    cxo,  12,   1,   4),
@@ -296,6 +296,18 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_gcc_sdcc2_4_apps_clk[] =
+{
+	F(   144000,    cxo,  16,   3,  25),
+	F(   400000,    cxo,  12,   1,   4),
+	F( 20000000,  gpll0,  15,   1,   2),
+	F( 25000000,  gpll0,  12,   1,   2),
+	F( 50000000,  gpll0,  12,   0,   0),
+	F(100000000,  gpll0,   6,   0,   0),
+	F(200000000,  gpll0,   3,   0,   0),
+	F_END
+};
+
 static struct rcg_clk sdcc1_apps_clk_src =
 {
 	.cmd_reg      = (uint32_t *) SDCC1_CMD_RCGR,
@@ -305,7 +317,7 @@
 	.d_reg        = (uint32_t *) SDCC1_D,
 
 	.set_rate     = clock_lib2_rcg_set_rate_mnd,
-	.freq_tbl     = ftbl_gcc_sdcc1_4_apps_clk,
+	.freq_tbl     = ftbl_gcc_sdcc1_apps_clk,
 	.current_freq = &rcg_dummy_freq,
 
 	.c = {
@@ -336,6 +348,46 @@
 	},
 };
 
+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_sdcc2_4_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,
+	},
+};
+
 static struct branch_clk gcc_sys_noc_usb30_axi_clk = {
 	.cbcr_reg    = (uint32_t *) SYS_NOC_USB3_AXI_CBCR,
 	.has_sibling = 1,
@@ -762,6 +814,9 @@
 	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),
 
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 9bbd4e4..103853c 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -74,7 +74,7 @@
 #define BOOT_DEVICE_MASK(val)   ((val & 0x3E) >>1)
 #define PMIC_WLED_SLAVE_ID      3
 
-static void set_sdc_power_ctrl(void);
+static void set_sdc_power_ctrl(uint8_t slot);
 static uint32_t mmc_pwrctl_base[] =
 	{ MSM_SDC1_BASE, MSM_SDC2_BASE };
 
@@ -178,27 +178,34 @@
 {
 }
 
-static void set_sdc_power_ctrl()
+static void set_sdc_power_ctrl(uint8_t slot)
 {
+	uint32_t reg = 0;
+
+	if (slot == 0x1)
+		reg = SDC1_HDRV_PULL_CTL;
+	else if (slot == 0x2)
+		reg = SDC2_HDRV_PULL_CTL;
+
 	/* 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_10MA, TLMM_HDRV_MASK },
+		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, reg },
+		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, reg },
+		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, reg },
 	};
 
 	/* 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 },
+		{ SDC1_CLK_PULL_CTL_OFF,  TLMM_NO_PULL, TLMM_PULL_MASK, reg },
+		{ SDC1_CMD_PULL_CTL_OFF,  TLMM_PULL_UP, TLMM_PULL_MASK, reg },
+		{ SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK, reg },
 	};
 
 	struct tlmm_cfgs sdc1_rclk_cfg[] =
 	{
-		{ SDC1_RCLK_PULL_CTL_OFF, TLMM_PULL_DOWN, TLMM_PULL_MASK },
+		{ SDC1_RCLK_PULL_CTL_OFF, TLMM_PULL_DOWN, TLMM_PULL_MASK, reg },
 	};
 
 	/* Set the drive strength & pull control values */
@@ -211,9 +218,6 @@
 {
 	struct mmc_config_data config = {0};
 
-	/* Set drive strength & pull ctrl values */
-	set_sdc_power_ctrl();
-
 	config.bus_width = DATA_BUS_WIDTH_8BIT;
 	config.max_clk_rate = MMC_CLK_192MHZ;
 
@@ -224,6 +228,9 @@
 	config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
 	config.hs400_support = 1;
 
+	/* Set drive strength & pull ctrl values */
+	set_sdc_power_ctrl(config.slot);
+
 	if (!(dev = mmc_init(&config)))
 	{
 		/* Try slot 2 */
@@ -233,6 +240,9 @@
 		config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
 		config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
 
+		/* Set drive strength & pull ctrl values */
+		set_sdc_power_ctrl(config.slot);
+
 		if (!(dev = mmc_init(&config)))
 		{
 			dprintf(CRITICAL, "mmc init failed!");