summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorShravani Dingari <shravanid@nvidia.com>2013-04-12 11:26:25 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:09:59 -0700
commit18826fcbcc458b7893f2dd841d550e32ef738528 (patch)
tree468416dc61e124af624bbbfe699d0f3b905293b3 /drivers/crypto
parentebbeb78d9954e80dc590398f1692ab97b2aaa053 (diff)
crypto: tegra-se: Enable ROs, entropy clock for DRBG
Enable Ring Oscillators for DRBG during SE initialization and also entropy clock required for the ENTROPY source Bug 1194672, Bug 1250871 Change-Id: Id29be0f0525fa5cc037f52fb76442f4d443fb76e Signed-off-by: Shravani Dingari <shravanid@nvidia.com> Reviewed-on: http://git-master/r/211597 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mallikarjun Kasoju <mkasoju@nvidia.com> Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/tegra-se.c111
1 files changed, 91 insertions, 20 deletions
diff --git a/drivers/crypto/tegra-se.c b/drivers/crypto/tegra-se.c
index eb0095e89cfa..d50896ec96e8 100644
--- a/drivers/crypto/tegra-se.c
+++ b/drivers/crypto/tegra-se.c
@@ -42,7 +42,6 @@
#include <crypto/sha.h>
#include <linux/pm_runtime.h>
#include <mach/hardware.h>
-
#include <mach/pm_domains.h>
#include "tegra-se.h"
@@ -82,6 +81,7 @@ struct tegra_se_chipdata {
bool cprng_supported;
bool drbg_supported;
bool rsa_supported;
+ bool drbg_src_entropy_clk_enable;
unsigned long aes_freq;
unsigned long rng_freq;
unsigned long sha1_freq;
@@ -99,6 +99,7 @@ struct tegra_se_dev {
int irq; /* irq allocated */
spinlock_t lock; /* spin lock */
struct clk *pclk; /* Security Engine clock */
+ struct clk *enclk; /* Entropy clock */
struct crypto_queue queue; /* Security Engine crypto queue */
struct tegra_se_slot *slot_list; /* pointer to key slots */
struct tegra_se_rsa_slot *rsa_slot_list; /* rsa key slot pointer */
@@ -199,7 +200,6 @@ static struct workqueue_struct *se_work_q;
#define PMC_SCRATCH43_REG_OFFSET 0x22c
#define GET_MSB(x) ((x) >> (8*sizeof(x)-1))
static int force_reseed_count;
-static int drbg_ro_entropy_src_enabled;
static void tegra_se_leftshift_onebit(u8 *in_buf, u32 size, u8 *org_msb)
{
u8 carry;
@@ -1321,23 +1321,6 @@ static int tegra_se_rng_drbg_init(struct crypto_tfm *tfm)
return -ENOMEM;
}
- /* take access to the hw */
- mutex_lock(&se_hw_lock);
- pm_runtime_get_sync(se_dev->dev);
-
- if (!drbg_ro_entropy_src_enabled
- && (tegra_get_chipid() != TEGRA_CHIPID_TEGRA3)
- && (tegra_get_chipid() != TEGRA_CHIPID_TEGRA11)) {
- se_writel(se_dev,
- SE_RNG_SRC_CONFIG_RO_ENT_SRC(DRBG_RO_ENT_SRC_ENABLE)
- |SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(DRBG_RO_ENT_SRC_LOCK_ENABLE),
- SE_RNG_SRC_CONFIG_REG_OFFSET);
- drbg_ro_entropy_src_enabled = 1;
- }
-
- pm_runtime_put(se_dev->dev);
- mutex_unlock(&se_hw_lock);
-
return 0;
}
@@ -1360,6 +1343,15 @@ static int tegra_se_rng_drbg_get_random(struct crypto_rng *tfm,
mutex_lock(&se_hw_lock);
pm_runtime_get_sync(se_dev->dev);
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable) {
+ /* enable clock for entropy */
+ ret = clk_enable(se_dev->enclk);
+ if (ret) {
+ dev_err(se_dev->dev, "entropy clock enable failed\n");
+ return ret;
+ }
+ }
+
*se_dev->src_ll_buf = 0;
*se_dev->dst_ll_buf = 0;
src_ll = (struct tegra_se_ll *)(se_dev->src_ll_buf + 1);
@@ -1403,6 +1395,9 @@ static int tegra_se_rng_drbg_get_random(struct crypto_rng *tfm,
dma_sync_single_for_cpu(se_dev->dev, rng_ctx->dt_buf_adr,
TEGRA_SE_RNG_DT_SIZE, DMA_FROM_DEVICE);
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable)
+ clk_disable(se_dev->enclk);
+
pm_runtime_put(se_dev->dev);
mutex_unlock(&se_hw_lock);
@@ -2671,6 +2666,33 @@ static int tegra_se_probe(struct platform_device *pdev)
}
#endif
+ /* take access to the hw */
+ mutex_lock(&se_hw_lock);
+ pm_runtime_get_sync(se_dev->dev);
+
+ if (se_dev->chipdata->drbg_supported
+ && (tegra_get_chipid() != TEGRA_CHIPID_TEGRA11)) {
+ se_writel(se_dev,
+ SE_RNG_SRC_CONFIG_RO_ENT_SRC(DRBG_RO_ENT_SRC_ENABLE)
+ |SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(DRBG_RO_ENT_SRC_LOCK_ENABLE),
+ SE_RNG_SRC_CONFIG_REG_OFFSET);
+ se_dev->chipdata->drbg_src_entropy_clk_enable = true;
+ }
+
+ pm_runtime_put(se_dev->dev);
+ mutex_unlock(&se_hw_lock);
+
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable) {
+ /* Initialize the entropy clock */
+ se_dev->enclk = clk_get_sys("entropy", NULL);
+ if (IS_ERR(se_dev->enclk)) {
+ err = PTR_ERR(se_dev->enclk);
+ dev_err(se_dev->dev,
+ "entropy clock init failed(%d)\n", err);
+ goto clean;
+ }
+ }
+
dev_info(se_dev->dev, "%s: complete", __func__);
return 0;
@@ -2687,6 +2709,9 @@ clean:
if (se_work_q)
destroy_workqueue(se_work_q);
+ if (se_dev->enclk)
+ clk_put(se_dev->enclk);
+
if (se_dev->pclk)
clk_put(se_dev->pclk);
@@ -2723,6 +2748,10 @@ static int tegra_se_remove(struct platform_device *pdev)
crypto_unregister_alg(&aes_algs[i]);
for (i = 0; i < ARRAY_SIZE(hash_algs); i++)
crypto_unregister_ahash(&hash_algs[i]);
+
+ if (se_dev->enclk)
+ clk_put(se_dev->enclk);
+
if (se_dev->pclk)
clk_put(se_dev->pclk);
tegra_se_free_ll_buf(se_dev);
@@ -2785,6 +2814,15 @@ static int tegra_se_generate_srk(struct tegra_se_dev *se_dev)
mutex_lock(&se_hw_lock);
pm_runtime_get_sync(se_dev->dev);
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable) {
+ /* enable clock for entropy */
+ ret = clk_enable(se_dev->enclk);
+ if (ret) {
+ dev_err(se_dev->dev, "entropy clock enable failed\n");
+ return ret;
+ }
+ }
+
ret = tegra_se_generate_rng_key(se_dev);
if (ret) {
pm_runtime_put(se_dev->dev);
@@ -2824,6 +2862,9 @@ static int tegra_se_generate_srk(struct tegra_se_dev *se_dev)
}
ret = tegra_se_start_operation(se_dev, TEGRA_SE_KEY_128_SIZE, false);
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable)
+ clk_disable(se_dev->enclk);
+
pm_runtime_put(se_dev->dev);
mutex_unlock(&se_hw_lock);
@@ -2839,6 +2880,15 @@ static int tegra_se_lp_generate_random_data(struct tegra_se_dev *se_dev)
mutex_lock(&se_hw_lock);
pm_runtime_get_sync(se_dev->dev);
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable) {
+ /* enable clock for entropy */
+ ret = clk_enable(se_dev->enclk);
+ if (ret) {
+ dev_err(se_dev->dev, "entropy clock enable failed\n");
+ return ret;
+ }
+ }
+
*se_dev->src_ll_buf = 0;
*se_dev->dst_ll_buf = 0;
src_ll = (struct tegra_se_ll *)(se_dev->src_ll_buf + 1);
@@ -2874,11 +2924,13 @@ static int tegra_se_lp_generate_random_data(struct tegra_se_dev *se_dev)
dma_sync_single_for_cpu(se_dev->dev, se_dev->ctx_save_buf_adr,
SE_CONTEXT_SAVE_RANDOM_DATA_SIZE, DMA_FROM_DEVICE);
+ if (se_dev->chipdata->drbg_src_entropy_clk_enable)
+ clk_disable(se_dev->enclk);
+
pm_runtime_put(se_dev->dev);
mutex_unlock(&se_hw_lock);
return ret;
-
}
static int tegra_se_lp_encrypt_context_data(struct tegra_se_dev *se_dev,
@@ -3244,8 +3296,27 @@ out:
static int tegra_se_resume(struct device *dev)
{
+ struct tegra_se_dev *se_dev = sg_tegra_se_dev;
+
/* pair with tegra_se_suspend, no need to actually enable clock */
pm_runtime_get_noresume(dev);
+
+ /* take access to the hw */
+ mutex_lock(&se_hw_lock);
+ pm_runtime_get_sync(se_dev->dev);
+
+ if ((tegra_get_chipid() != TEGRA_CHIPID_TEGRA3)
+ && (tegra_get_chipid() != TEGRA_CHIPID_TEGRA11)) {
+ se_writel(se_dev,
+ SE_RNG_SRC_CONFIG_RO_ENT_SRC(DRBG_RO_ENT_SRC_ENABLE)
+ |SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(DRBG_RO_ENT_SRC_LOCK_ENABLE),
+ SE_RNG_SRC_CONFIG_REG_OFFSET);
+ se_dev->chipdata->drbg_src_entropy_clk_enable = true;
+ }
+
+ pm_runtime_put(se_dev->dev);
+ mutex_unlock(&se_hw_lock);
+
return 0;
}
#endif