msm: 8064: Enable crypto engine.

-add new clock - ce3_core_src_clk to 8064 target.
-ce3_p_clk and ce3_core_clk are derived from ce3_core_src_clk.
-ce3 core src clock expects that the driver(qce40) set the clock
 rate before the clock is enabled.
-set ce3_core_src_clk rate to 100mhz.
-add new DMA channels for APQ8064.

Change-Id: I3f0897b43d5d58a60a1df4f61a241868b8b9a926
Signed-off-by: Ramesh Masavarapu <rameshm@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index b131989..6662751 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -18,6 +18,8 @@
 #include <linux/slimbus/slimbus.h>
 #include <linux/msm_ssbi.h>
 #include <linux/spi/spi.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_data/qcom_crypto_device.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -37,6 +39,7 @@
 #include <mach/msm_memtypes.h>
 #include <linux/bootmem.h>
 #include <asm/setup.h>
+#include <mach/dma.h>
 
 #include "msm_watchdog.h"
 #include "board-apq8064.h"
@@ -443,6 +446,118 @@
 	apq8064_add_sdcc(3, apq8064_sdc3_pdata);
 }
 
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+
+#define QCE_SIZE		0x10000
+#define QCE_0_BASE		0x11000000
+
+#define QCE_HW_KEY_SUPPORT	0
+#define QCE_SHA_HMAC_SUPPORT	1
+#define QCE_SHARE_CE_RESOURCE	3
+#define QCE_CE_SHARED		0
+
+static struct resource qcrypto_resources[] = {
+	[0] = {
+		.start = QCE_0_BASE,
+		.end = QCE_0_BASE + QCE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.name = "crypto_channels",
+		.start = DMOV8064_CE_IN_CHAN,
+		.end = DMOV8064_CE_OUT_CHAN,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.name = "crypto_crci_in",
+		.start = DMOV8064_CE_IN_CRCI,
+		.end = DMOV8064_CE_IN_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name = "crypto_crci_out",
+		.start = DMOV8064_CE_OUT_CRCI,
+		.end = DMOV8064_CE_OUT_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct resource qcedev_resources[] = {
+	[0] = {
+		.start = QCE_0_BASE,
+		.end = QCE_0_BASE + QCE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.name = "crypto_channels",
+		.start = DMOV8064_CE_IN_CHAN,
+		.end = DMOV8064_CE_OUT_CHAN,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.name = "crypto_crci_in",
+		.start = DMOV8064_CE_IN_CRCI,
+		.end = DMOV8064_CE_IN_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name = "crypto_crci_out",
+		.start = DMOV8064_CE_OUT_CRCI,
+		.end = DMOV8064_CE_OUT_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+
+static struct msm_ce_hw_support qcrypto_ce_hw_suppport = {
+	.ce_shared = QCE_CE_SHARED,
+	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
+	.hw_key_support = QCE_HW_KEY_SUPPORT,
+	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
+};
+
+static struct platform_device qcrypto_device = {
+	.name		= "qcrypto",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(qcrypto_resources),
+	.resource	= qcrypto_resources,
+	.dev		= {
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &qcrypto_ce_hw_suppport,
+	},
+};
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+
+static struct msm_ce_hw_support qcedev_ce_hw_suppport = {
+	.ce_shared = QCE_CE_SHARED,
+	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
+	.hw_key_support = QCE_HW_KEY_SUPPORT,
+	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
+};
+
+static struct platform_device qcedev_device = {
+	.name		= "qce",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(qcedev_resources),
+	.resource	= qcedev_resources,
+	.dev		= {
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &qcedev_ce_hw_suppport,
+	},
+};
+#endif
+
+
 #define MSM_SHARED_RAM_PHYS 0x80000000
 static void __init apq8064_map_io(void)
 {
@@ -526,6 +641,15 @@
 	&msm8064_device_saw_regulator_core1,
 	&msm8064_device_saw_regulator_core2,
 	&msm8064_device_saw_regulator_core3,
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
 };
 
 static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index aaf6c83..c16c2ee 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5158,8 +5158,14 @@
 	CLK_LOOKUP("usb_fs_sys_clk",	usb_fs1_sys_clk.c,	NULL),
 	CLK_LOOKUP("iface_clk",		ce1_p_clk.c,		NULL),
 	CLK_LOOKUP("core_clk",		ce1_core_clk.c,		NULL),
-	CLK_LOOKUP("ref_clk",		sata_phy_ref_clk.c,     NULL),
+	CLK_LOOKUP("ref_clk",		sata_phy_ref_clk.c,	NULL),
 	CLK_LOOKUP("cfg_clk",		sata_phy_cfg_clk.c,	NULL),
+	CLK_LOOKUP("iface_clk",		ce3_p_clk.c,		"qce.0"),
+	CLK_LOOKUP("iface_clk",		ce3_p_clk.c,		"qcrypto.0"),
+	CLK_LOOKUP("core_clk",		ce3_core_clk.c,		"qce.0"),
+	CLK_LOOKUP("core_clk",		ce3_core_clk.c,		"qcrypto.0"),
+	CLK_LOOKUP("ce3_core_src_clk",	ce3_src_clk.c,		"qce.0"),
+	CLK_LOOKUP("ce3_core_src_clk",	ce3_src_clk.c,		"qcrypto.0"),
 	CLK_LOOKUP("dma_bam_pclk",	dma_bam_p_clk.c,	NULL),
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,		NULL),
 	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,		NULL),
@@ -5178,9 +5184,6 @@
 	CLK_LOOKUP("iface_clk",		sdc3_p_clk.c,		"msm_sdcc.3"),
 	CLK_LOOKUP("iface_clk",		sdc4_p_clk.c,		"msm_sdcc.4"),
 	CLK_LOOKUP("iface_clk",		pcie_p_clk.c,		NULL),
-	CLK_LOOKUP("core_src_clk",	ce3_src_clk.c,		NULL),
-	CLK_LOOKUP("core_clk",          ce3_core_clk.c,         NULL),
-	CLK_LOOKUP("iface_clk",         ce3_p_clk.c,            NULL),
 	CLK_LOOKUP("core_clk",		adm0_clk.c,		"msm_dmov"),
 	CLK_LOOKUP("iface_clk",		adm0_p_clk.c,		"msm_dmov"),
 	CLK_LOOKUP("iface_clk",		pmic_arb0_p_clk.c,	NULL),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 9b8d5ac..afc2649 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -761,6 +761,12 @@
 	CLK_DUMMY("dfab_clk",		DFAB_CLK,		NULL, 0),
 	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,		NULL, 0),
 	CLK_DUMMY("mem_clk",		EBI1_ADM_CLK,	  "msm_dmov", 0),
+	CLK_DUMMY("ce3_core_src_clk",	CE3_SRC_CLK,     "qce.0", OFF),
+	CLK_DUMMY("ce3_core_src_clk",	CE3_SRC_CLK, "qcrypto.0", OFF),
+	CLK_DUMMY("core_clk",		CE3_CORE_CLK,	      "qce.0", OFF),
+	CLK_DUMMY("core_clk",		CE3_CORE_CLK,	  "qcrypto.0", OFF),
+	CLK_DUMMY("iface_clk",		CE3_P_CLK,	     "qce0.0", OFF),
+	CLK_DUMMY("iface_clk",		CE3_P_CLK,	  "qcrypto.0", OFF),
 };
 
 struct clock_init_data apq8064_dummy_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 1474fcb..3cb79b7 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -245,6 +245,13 @@
 #define DMOV_HSUART2_RX_CRCI   15
 #endif
 
+/* channels for APQ8064 */
+#define DMOV8064_CE_IN_CHAN        2
+#define DMOV8064_CE_IN_CRCI       14
+
+#define DMOV8064_CE_OUT_CHAN       3
+#define DMOV8064_CE_OUT_CRCI       15
+
 
 /* no client rate control ifc (eg, ram) */
 #define DMOV_NONE_CRCI        0
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index 893933b..60a5aff 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -58,8 +58,9 @@
 	void __iomem *iobase;	    /* Virtual io base of CE HW  */
 	unsigned int phy_iobase;    /* Physical io base of CE HW    */
 
-	struct clk *ce_core_clk;	    /* Handle to CE clk */
-	struct clk *ce_clk;	    /* Handle to CE clk */
+	struct clk *ce_core_src_clk;	/* Handle to CE src clk*/
+	struct clk *ce_core_clk;	/* Handle to CE clk */
+	struct clk *ce_clk;		/* Handle to CE clk */
 
 	qce_comp_func_ptr_t qce_cb;	/* qce callback function pointer */
 
@@ -2391,6 +2392,8 @@
 	struct resource *resource;
 	struct clk *ce_core_clk;
 	struct clk *ce_clk;
+	struct clk *ce_core_src_clk;
+	int ret = 0;
 
 	pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
 	if (!pce_dev) {
@@ -2461,10 +2464,26 @@
 		goto err;
 	}
 
+	/* Get CE3 src core clk. */
+	ce_core_src_clk = clk_get(pce_dev->pdev, "ce3_core_src_clk");
+	if (!IS_ERR(ce_core_src_clk)) {
+		pce_dev->ce_core_src_clk = ce_core_src_clk;
+
+		/* Set the core src clk @100Mhz */
+		ret = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
+		if (ret) {
+			clk_put(pce_dev->ce_core_src_clk);
+			goto err;
+		}
+	} else
+		pce_dev->ce_core_src_clk = NULL;
+
 	/* Get CE core clk */
 	ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
 	if (IS_ERR(ce_core_clk)) {
 		*rc = PTR_ERR(ce_core_clk);
+		if (pce_dev->ce_core_src_clk != NULL)
+			clk_put(pce_dev->ce_core_src_clk);
 		goto err;
 	}
 	pce_dev->ce_core_clk = ce_core_clk;
@@ -2472,6 +2491,8 @@
 	ce_clk = clk_get(pce_dev->pdev, "iface_clk");
 	if (IS_ERR(ce_clk)) {
 		*rc = PTR_ERR(ce_clk);
+		if (pce_dev->ce_core_src_clk != NULL)
+			clk_put(pce_dev->ce_core_src_clk);
 		clk_put(pce_dev->ce_core_clk);
 		goto err;
 	}
@@ -2480,6 +2501,8 @@
 	/* Enable CE core clk */
 	*rc = clk_enable(pce_dev->ce_core_clk);
 	if (*rc) {
+		if (pce_dev->ce_core_src_clk != NULL)
+			clk_put(pce_dev->ce_core_src_clk);
 		clk_put(pce_dev->ce_core_clk);
 		clk_put(pce_dev->ce_clk);
 		goto err;
@@ -2488,6 +2511,8 @@
 		*rc = clk_enable(pce_dev->ce_clk);
 		if (*rc) {
 			clk_disable(pce_dev->ce_core_clk);
+			if (pce_dev->ce_core_src_clk != NULL)
+				clk_put(pce_dev->ce_core_src_clk);
 			clk_put(pce_dev->ce_core_clk);
 			clk_put(pce_dev->ce_clk);
 			goto err;
@@ -2539,6 +2564,9 @@
 	clk_disable(pce_dev->ce_clk);
 	clk_disable(pce_dev->ce_core_clk);
 
+	if (pce_dev->ce_core_src_clk != NULL)
+		clk_put(pce_dev->ce_core_src_clk);
+
 	clk_put(pce_dev->ce_clk);
 	clk_put(pce_dev->ce_core_clk);
 
@@ -2571,4 +2599,4 @@
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
 MODULE_DESCRIPTION("Crypto Engine driver");
-MODULE_VERSION("2.13");
+MODULE_VERSION("2.14");