target: msm8916: Enable crypto and SSD features for MSM8916

Enable crypto engine for image authentication and SSD for loading
the SSD keystore.

Change-Id: Ie35f44bb054894e328199ad7170ff648b3221e5a
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index 090da0a..683cb4a 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -44,6 +44,10 @@
 #include <platform/gpio.h>
 #include <platform/gpio.h>
 #include <platform/irqs.h>
+#include <platform/clock.h>
+#include <crypto5_wrapper.h>
+#include <partition_parser.h>
+#include <stdlib.h>
 
 #if LONG_PRESS_POWER_ON
 #include <shutdown_detect.h>
@@ -63,6 +67,15 @@
 
 #define FASTBOOT_MODE           0x77665500
 
+#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
+
 static void set_sdc_power_ctrl(void);
 
 struct mmc_device *dev;
@@ -182,6 +195,9 @@
 	/* turn on vibrator to indicate that phone is booting up to end user */
 	vib_timed_turn_on(VIBRATE_TIME);
 #endif
+
+	if (target_use_signed_kernel())
+		target_crypto_init_params();
 }
 
 void target_serialno(unsigned char *buf)
@@ -437,6 +453,12 @@
 
 	mmc_put_card_to_sleep(dev);
 	sdhci_mode_disable(&dev->host);
+
+	if (target_is_ssd_enabled())
+		clock_ce_disable(CE1_INSTANCE);
+
+	if (crypto_initialized())
+		crypto_eng_cleanup();
 }
 
 /* Do any target specific intialization needed before entering fastboot mode */
@@ -444,6 +466,11 @@
 {
 	/* Set the BOOT_DONE flag in PM8916 */
 	pm8x41_set_boot_done();
+
+	if (target_is_ssd_enabled()) {
+		clock_ce_enable(CE1_INSTANCE);
+		target_load_ssd_keystore();
+	}
 }
 
 int set_download_mode(enum dload_mode mode)
@@ -455,3 +482,81 @@
 
 	return ret;
 }
+
+void target_load_ssd_keystore(void)
+{
+	uint64_t ptn;
+	int      index;
+	uint64_t size;
+	uint32_t *buffer = NULL;
+
+	if (!target_is_ssd_enabled())
+		return;
+
+	index = partition_get_index("ssd");
+
+	ptn = partition_get_offset(index);
+	if (ptn == 0){
+		dprintf(CRITICAL, "Error: ssd partition not found\n");
+		return;
+	}
+
+	size = partition_get_size(index);
+	if (size == 0) {
+		dprintf(CRITICAL, "Error: invalid ssd partition size\n");
+		return;
+	}
+
+	buffer = memalign(CACHE_LINE, ROUNDUP(size, CACHE_LINE));
+	if (!buffer) {
+		dprintf(CRITICAL, "Error: allocating memory for ssd buffer\n");
+		return;
+	}
+
+	if (mmc_read(ptn, buffer, size)) {
+		dprintf(CRITICAL, "Error: cannot read data\n");
+		free(buffer);
+		return;
+	}
+
+	clock_ce_enable(CE1_INSTANCE);
+	scm_protect_keystore(buffer, size);
+	clock_ce_disable(CE1_INSTANCE);
+	free(buffer);
+}
+
+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);
+}