platform/target: mdm9607: Changes supports signed boot image authentication

These changes are needed for authenticating the boot.img
signed with traditional way.

Change-Id: Ib993e70f890b137f601e325c77e1638508b33a19
diff --git a/platform/mdm9607/acpuclock.c b/platform/mdm9607/acpuclock.c
index bd068ad..6c8e838 100644
--- a/platform/mdm9607/acpuclock.c
+++ b/platform/mdm9607/acpuclock.c
@@ -115,3 +115,107 @@
 		ASSERT(0);
 	}
 }
+
+void clock_ce_enable(uint8_t instance)
+{
+	int ret;
+	char clk_name[64];
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
+	ret = clk_get_set_enable(clk_name, 160000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, 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, sizeof(clk_name), "ce%u_src_clk", instance);
+	src_clk = clk_get(clk_name);
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
+	ahb_clk = clk_get(clk_name);
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
+	axi_clk = clk_get(clk_name);
+
+	snprintf(clk_name, sizeof(clk_name), "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)
+{
+	/* Start the block reset for CE */
+	writel(1, GCC_CRYPTO_BCR);
+
+	udelay(2);
+
+	/* Take CE block out of reset */
+	writel(0, GCC_CRYPTO_BCR);
+
+	udelay(2);
+}
+
+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/mdm9607/include/platform/iomap.h b/platform/mdm9607/include/platform/iomap.h
index c933148..00c98a5 100644
--- a/platform/mdm9607/include/platform/iomap.h
+++ b/platform/mdm9607/include/platform/iomap.h
@@ -85,6 +85,12 @@
 /* CRYPTO ENGINE */
 #define  MSM_CE1_BASE                      0x073A000
 #define  MSM_CE1_BAM_BASE                  0x0704000
+#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 */
diff --git a/platform/mdm9607/mdm9607-clock.c b/platform/mdm9607/mdm9607-clock.c
index fc1e85a..0515842 100644
--- a/platform/mdm9607/mdm9607-clock.c
+++ b/platform/mdm9607/mdm9607-clock.c
@@ -215,6 +215,56 @@
 		.ops      = &clk_ops_branch,
 	},
 };
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F(160000000,  gpll0,   5,   0,   0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_CRYPTO_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_CRYPTO_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_CRYPTO_CBCR,
+	.vote_reg      = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask       = BIT(2),
+
+	.c = {
+		.dbg_name  = "gcc_ce1_clk",
+		.ops       = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CRYPTO_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(0),
+
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CRYPTO_AXI_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(1),
+
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
 
 /* Clock lookup table */
 static struct clk_lookup mdm_clocks_9607[] =
@@ -225,6 +275,10 @@
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
 	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_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/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index ab792b4..f426e93 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -539,6 +539,11 @@
 			$(LOCAL_DIR)/spmi.o \
 			$(LOCAL_DIR)/bam.o \
 			$(LOCAL_DIR)/qpic_nand.o \
+			$(LOCAL_DIR)/crypto_hash.o \
+			$(LOCAL_DIR)/crypto5_eng.o \
+			$(LOCAL_DIR)/crypto5_wrapper.o \
+			$(LOCAL_DIR)/certificate.o \
+			$(LOCAL_DIR)/image_verify.o \
 			$(LOCAL_DIR)/flash-ubi.o \
 			$(LOCAL_DIR)/scm.o \
 			$(LOCAL_DIR)/dev_tree.o
diff --git a/target/mdm9607/init.c b/target/mdm9607/init.c
index 1fba03c..b59b7b9 100644
--- a/target/mdm9607/init.c
+++ b/target/mdm9607/init.c
@@ -85,6 +85,16 @@
 #define LAST_NAND_PTN_LEN_PATTERN 0xFFFFFFFF
 #define UBI_CMDLINE " rootfstype=ubifs rootflags=bulk_read"
 
+#define CE1_INSTANCE            1
+#define CE_EE                   1
+#define CE_FIFO_SIZE            64
+#define CE_READ_PIPE            3
+#define CE_WRITE_PIPE           2
+#define CE_READ_PIPE_LOCK_GRP   0
+#define CE_WRITE_PIPE_LOCK_GRP  0
+#define CE_ARRAY_SIZE           20
+#define SUB_TYPE_SKUT           0x0A
+
 struct qpic_nand_init_config config;
 
 void update_ptable_names(void)
@@ -188,6 +198,9 @@
 
 	update_ptable_names();
 	flash_set_ptable(&flash_ptable);
+
+	if (target_use_signed_kernel())
+		target_crypto_init_params();
 }
 
 /* Identify the current target */
@@ -297,6 +310,8 @@
 
 void target_uninit(void)
 {
+	if (crypto_initialized())
+		crypto_eng_cleanup();
 }
 
 void reboot_device(unsigned reboot_reason)
@@ -325,3 +340,38 @@
 	dprintf(CRITICAL, "Rebooting failed\n");
 	return;
 }
+
+crypto_engine_type board_ce_type(void)
+{
+	return CRYPTO_ENGINE_TYPE_HW;
+}
+
+/* Set up params for h/w CE. */
+void target_crypto_init_params()
+{
+	struct crypto_init_params ce_params;
+
+	/* Set up base addresses and instance. */
+	ce_params.crypto_instance  = CE1_INSTANCE;
+	ce_params.crypto_base      = MSM_CE1_BASE;
+	ce_params.bam_base         = MSM_CE1_BAM_BASE;
+
+	/* Set up BAM config. */
+	ce_params.bam_ee               = CE_EE;
+	ce_params.pipes.read_pipe      = CE_READ_PIPE;
+	ce_params.pipes.write_pipe     = CE_WRITE_PIPE;
+	ce_params.pipes.read_pipe_grp  = CE_READ_PIPE_LOCK_GRP;
+	ce_params.pipes.write_pipe_grp = CE_WRITE_PIPE_LOCK_GRP;
+
+	/* Assign buffer sizes. */
+	ce_params.num_ce           = CE_ARRAY_SIZE;
+	ce_params.read_fifo_size   = CE_FIFO_SIZE;
+	ce_params.write_fifo_size  = CE_FIFO_SIZE;
+
+	/* BAM is initialized by TZ for this platform.
+	* Do not do it again as the initialization address space
+	* is locked.
+	*/
+	ce_params.do_bam_init      = 0;
+	crypto_init_params(&ce_params);
+}