msm8610: enable SSD support

Change-Id: I754cb89ddb8a8304213242ec7e52ce95c8327310
diff --git a/platform/msm8610/acpuclock.c b/platform/msm8610/acpuclock.c
index 4376e68..bbc725f 100644
--- a/platform/msm8610/acpuclock.c
+++ b/platform/msm8610/acpuclock.c
@@ -166,10 +166,6 @@
 	}
 }
 
-void clock_config_ce(uint8_t instance)
-{
-}
-
 /* Configure MDP clock */
 void mdp_clock_enable(void)
 {
@@ -445,3 +441,119 @@
 	vco_enable(0);
 	clk_disable(clk_get("dsi_ahb_clk"));
 }
+
+
+void clock_ce_enable(uint8_t instance)
+{
+	int ret;
+	char clk_name[64];
+
+	snprintf(clk_name, 64, "ce%u_src_clk", instance);
+	ret = clk_get_set_enable(clk_name, 100000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_core_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Wait for 48 * #pipes cycles.
+	 * This is necessary as immediately after an access control reset (boot up)
+	 * or a debug re-enable, the Crypto core sequentially clears its internal
+	 * pipe key storage memory. If pipe key initialization writes are attempted
+	 * during this time, they may be overwritten by the internal clearing logic.
+	 */
+	udelay(1);
+}
+
+void clock_ce_disable(uint8_t instance)
+{
+	struct clk *ahb_clk;
+	struct clk *cclk;
+	struct clk *axi_clk;
+	struct clk *src_clk;
+	char clk_name[64];
+
+	snprintf(clk_name, 64, "ce%u_src_clk", instance);
+	src_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+	ahb_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+	axi_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_core_clk", instance);
+	cclk    = clk_get(clk_name);
+
+	clk_disable(ahb_clk);
+	clk_disable(axi_clk);
+	clk_disable(cclk);
+	clk_disable(src_clk);
+
+	/* Some delay for the clocks to stabalize. */
+	udelay(1);
+}
+
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+	if (instance == 1)
+	{
+		/* Start the block reset for CE */
+		writel(1, GCC_CE1_BCR);
+
+		udelay(2);
+
+		/* Take CE block out of reset */
+		writel(0, GCC_CE1_BCR);
+
+		udelay(2);
+	}
+	else
+	{
+		dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
+		ASSERT(0);
+	}
+}
+
+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);
+
+}
diff --git a/platform/msm8610/include/platform/clock.h b/platform/msm8610/include/platform/clock.h
index de50978..df08046 100644
--- a/platform/msm8610/include/platform/clock.h
+++ b/platform/msm8610/include/platform/clock.h
@@ -79,5 +79,7 @@
 void mdp_clock_disable(void);
 void dsi_clock_enable(uint32_t dsiclk_rate, uint32_t byteclk_rate);
 void dsi_clock_disable(void);
+void clock_ce_enable(uint8_t instance);
+void clock_ce_disable(uint8_t instance);
 
 #endif
diff --git a/platform/msm8610/include/platform/iomap.h b/platform/msm8610/include/platform/iomap.h
index f9f1c27..7999453 100644
--- a/platform/msm8610/include/platform/iomap.h
+++ b/platform/msm8610/include/platform/iomap.h
@@ -246,4 +246,13 @@
 #define SDCC_HC_PWRCTL_MASK_REG     (0x000000E0)
 #define SDCC_HC_PWRCTL_CLEAR_REG    (0x000000E4)
 #define SDCC_HC_PWRCTL_CTL_REG      (0x000000E8)
+
+/* CE 1 */
+#define  GCC_CE1_BCR                (CLK_CTL_BASE + 0x1040)
+#define  GCC_CE1_CMD_RCGR           (CLK_CTL_BASE + 0x1050)
+#define  GCC_CE1_CFG_RCGR           (CLK_CTL_BASE + 0x1054)
+#define  GCC_CE1_CBCR               (CLK_CTL_BASE + 0x1044)
+#define  GCC_CE1_AXI_CBCR           (CLK_CTL_BASE + 0x1048)
+#define  GCC_CE1_AHB_CBCR           (CLK_CTL_BASE + 0x104C)
+
 #endif
diff --git a/platform/msm8610/msm8610-clock.c b/platform/msm8610/msm8610-clock.c
index 95cb4d3..f4cdd53 100644
--- a/platform/msm8610/msm8610-clock.c
+++ b/platform/msm8610/msm8610-clock.c
@@ -449,6 +449,58 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F( 50000000,  gpll0,  12,   0,   0),
+	F(100000000,  gpll0,   6,   0,   0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_CE1_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_CE1_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct vote_clk gcc_ce1_clk = {
+	.cbcr_reg      = (uint32_t *) GCC_CE1_CBCR,
+	.vote_reg      = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask       = BIT(5),
+
+	.c = {
+		.dbg_name  = "gcc_ce1_clk",
+		.ops       = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CE1_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(3),
+
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CE1_AXI_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(4),
+
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
 /* Clock lookup table */
 static struct clk_lookup msm_clocks_8610[] =
 {
@@ -478,6 +530,11 @@
 	CLK_LOOKUP("dsi_byte_clk",         dsi_byte_clk.c),
 	CLK_LOOKUP("dsi_esc_clk",          dsi_esc_clk.c),
 	CLK_LOOKUP("dsi_pclk_clk",         dsi_pclk_clk.c),
+
+	CLK_LOOKUP("ce1_ahb_clk",  gcc_ce1_ahb_clk.c),
+	CLK_LOOKUP("ce1_axi_clk",  gcc_ce1_axi_clk.c),
+	CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
+	CLK_LOOKUP("ce1_src_clk",  ce1_clk_src.c),
 };
 
 void platform_clock_init(void)
diff --git a/platform/msm8610/rules.mk b/platform/msm8610/rules.mk
index b050c3d..234432f 100644
--- a/platform/msm8610/rules.mk
+++ b/platform/msm8610/rules.mk
@@ -11,7 +11,7 @@
 
 DEFINES += PERIPH_BLK_BLSP=1
 DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
-	   MMC_SLOT=$(MMC_SLOT)
+	   MMC_SLOT=$(MMC_SLOT) SSD_ENABLE
 
 INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include