summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorMallikarjun Kasoju <mkasoju@nvidia.com>2012-12-05 18:14:58 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 00:48:31 -0700
commit788734ec425dfc8c30cffe25ad42bca6a48d6902 (patch)
tree1f8d920beab96e35c65bd87b81e64a7a620baacb /drivers/crypto
parent6e3ca84a7e6725d5da2b374c4fa6e447896052b6 (diff)
crypto: tegra-se: change SE freq based on algo
change S.E frequency based on the algorithm being used Bug 1014636 Change-Id: I49d1d15d0da0a9c76c3eda7d86872678dfe8d911 Signed-off-by: Venkatajagadish <vjagadish@nvidia.com> Signed-off-by: Mallikarjun Kasoju <mkasoju@nvidia.com> Reviewed-on: http://git-master/r/132551 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/tegra-se.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/drivers/crypto/tegra-se.c b/drivers/crypto/tegra-se.c
index b9b7399e332c..4a94ab0dbcfa 100644
--- a/drivers/crypto/tegra-se.c
+++ b/drivers/crypto/tegra-se.c
@@ -80,6 +80,14 @@ struct tegra_se_chipdata {
bool cprng_supported;
bool drbg_supported;
bool rsa_supported;
+ unsigned long aes_freq;
+ unsigned long rng_freq;
+ unsigned long sha1_freq;
+ unsigned long sha224_freq;
+ unsigned long sha256_freq;
+ unsigned long sha384_freq;
+ unsigned long sha512_freq;
+ unsigned long rsa_freq;
};
struct tegra_se_dev {
@@ -497,6 +505,8 @@ static void tegra_se_config_crypto(struct tegra_se_dev *se_dev,
enum tegra_se_aes_op_mode mode, bool encrypt, u8 slot_num, bool org_iv)
{
u32 val = 0;
+ unsigned long freq = 0;
+ int err = 0;
switch (mode) {
case SE_AES_OP_MODE_CMAC:
@@ -512,11 +522,13 @@ static void tegra_se_config_crypto(struct tegra_se_dev *se_dev,
SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
}
+ freq = se_dev->chipdata->aes_freq;
break;
case SE_AES_OP_MODE_RNG_X931:
val = SE_CRYPTO_INPUT_SEL(INPUT_AHB) |
SE_CRYPTO_XOR_POS(XOR_BYPASS) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
+ freq = se_dev->chipdata->rng_freq;
break;
case SE_AES_OP_MODE_RNG_DRBG:
val = SE_CRYPTO_INPUT_SEL(INPUT_RANDOM) |
@@ -524,6 +536,7 @@ static void tegra_se_config_crypto(struct tegra_se_dev *se_dev,
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA11))
val = val | SE_CRYPTO_KEY_INDEX(slot_num);
+ freq = se_dev->chipdata->rng_freq;
break;
case SE_AES_OP_MODE_ECB:
if (encrypt) {
@@ -535,18 +548,21 @@ static void tegra_se_config_crypto(struct tegra_se_dev *se_dev,
SE_CRYPTO_XOR_POS(XOR_BYPASS) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
}
+ freq = se_dev->chipdata->aes_freq;
break;
case SE_AES_OP_MODE_CTR:
val = SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
SE_CRYPTO_VCTRAM_SEL(VCTRAM_AHB) |
SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
+ freq = se_dev->chipdata->aes_freq;
break;
case SE_AES_OP_MODE_OFB:
val = SE_CRYPTO_INPUT_SEL(INPUT_AESOUT) |
SE_CRYPTO_VCTRAM_SEL(VCTRAM_AHB) |
SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
+ freq = se_dev->chipdata->aes_freq;
break;
default:
dev_warn(se_dev->dev, "Invalid operation mode\n");
@@ -564,6 +580,12 @@ static void tegra_se_config_crypto(struct tegra_se_dev *se_dev,
SE_CRYPTO_IV_SEL(IV_UPDATED));
}
+ err = clk_set_rate(se_dev->pclk, freq);
+ if (err) {
+ dev_err(se_dev->dev, "clock set_rate failed.\n");
+ return;
+ }
+
/* enable hash for CMAC */
if (mode == SE_AES_OP_MODE_CMAC)
val |= SE_CRYPTO_HASH(HASH_ENABLE);
@@ -599,9 +621,11 @@ static void tegra_se_config_crypto(struct tegra_se_dev *se_dev,
}
-static void tegra_se_config_sha(struct tegra_se_dev *se_dev, u32 count)
+static void tegra_se_config_sha(struct tegra_se_dev *se_dev, u32 count,
+ unsigned long freq)
{
int i;
+ int err = 0;
se_writel(se_dev, (count * 8), SE_SHA_MSG_LENGTH_REG_OFFSET);
se_writel(se_dev, (count * 8), SE_SHA_MSG_LEFT_REG_OFFSET);
@@ -609,6 +633,12 @@ static void tegra_se_config_sha(struct tegra_se_dev *se_dev, u32 count)
se_writel(se_dev, 0, SE_SHA_MSG_LENGTH_REG_OFFSET + (4 * i));
se_writel(se_dev, 0, SE_SHA_MSG_LEFT_REG_OFFSET + (4 * i));
}
+
+ err = clk_set_rate(se_dev->pclk, freq);
+ if (err) {
+ dev_err(se_dev->dev, "clock set_rate failed.\n");
+ return;
+ }
se_writel(se_dev, SHA_ENABLE, SE_SHA_CONFIG_REG_OFFSET);
}
@@ -1369,26 +1399,37 @@ int tegra_se_sha_final(struct ahash_request *req)
struct scatterlist *src_sg;
struct tegra_se_ll *src_ll;
u32 total, num_sgs;
+ unsigned long freq = 0;
int err = 0;
int chained;
if (!req->nbytes)
return -EINVAL;
- if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE)
+ if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE) {
sha_ctx->op_mode = SE_AES_OP_MODE_SHA1;
+ freq = se_dev->chipdata->sha1_freq;
+ }
- if (crypto_ahash_digestsize(tfm) == SHA224_DIGEST_SIZE)
+ if (crypto_ahash_digestsize(tfm) == SHA224_DIGEST_SIZE) {
sha_ctx->op_mode = SE_AES_OP_MODE_SHA224;
+ freq = se_dev->chipdata->sha224_freq;
+ }
- if (crypto_ahash_digestsize(tfm) == SHA256_DIGEST_SIZE)
+ if (crypto_ahash_digestsize(tfm) == SHA256_DIGEST_SIZE) {
sha_ctx->op_mode = SE_AES_OP_MODE_SHA256;
+ freq = se_dev->chipdata->sha256_freq;
+ }
- if (crypto_ahash_digestsize(tfm) == SHA384_DIGEST_SIZE)
+ if (crypto_ahash_digestsize(tfm) == SHA384_DIGEST_SIZE) {
sha_ctx->op_mode = SE_AES_OP_MODE_SHA384;
+ freq = se_dev->chipdata->sha384_freq;
+ }
- if (crypto_ahash_digestsize(tfm) == SHA512_DIGEST_SIZE)
+ if (crypto_ahash_digestsize(tfm) == SHA512_DIGEST_SIZE) {
sha_ctx->op_mode = SE_AES_OP_MODE_SHA512;
+ freq = se_dev->chipdata->sha512_freq;
+ }
/* take access to the hw */
mutex_lock(&se_hw_lock);
@@ -1412,7 +1453,7 @@ int tegra_se_sha_final(struct ahash_request *req)
src_ll, total);
tegra_se_config_algo(se_dev, sha_ctx->op_mode, false, 0);
- tegra_se_config_sha(se_dev, req->nbytes);
+ tegra_se_config_sha(se_dev, req->nbytes, freq);
err = tegra_se_start_operation(se_dev, 0, false);
if (!err) {
tegra_se_read_hash_result(se_dev, req->result,
@@ -1871,6 +1912,8 @@ int tegra_se_rsa_setkey(struct crypto_ahash *tfm, const u8 *key,
u32 *pkeydata = (u32 *)key;
s32 i = 0;
struct tegra_se_rsa_slot *pslot;
+ unsigned long freq = 0;
+ int err = 0;
if (!ctx || !key)
return -EINVAL;
@@ -1891,6 +1934,13 @@ int tegra_se_rsa_setkey(struct crypto_ahash *tfm, const u8 *key,
((module_key_length / 64) <= 4)))
return -EINVAL;
+ freq = se_dev->chipdata->rsa_freq;
+ err = clk_set_rate(se_dev->pclk, freq);
+ if (err) {
+ dev_err(se_dev->dev, "clock set_rate failed.\n");
+ return err;
+ }
+
/* take access to the hw */
mutex_lock(&se_hw_lock);
pm_runtime_get_sync(se_dev->dev);
@@ -3152,12 +3202,27 @@ static struct tegra_se_chipdata tegra_se_chipdata = {
.rsa_supported = false,
.cprng_supported = true,
.drbg_supported = false,
+ .aes_freq = 300000000,
+ .rng_freq = 300000000,
+ .sha1_freq = 300000000,
+ .sha224_freq = 300000000,
+ .sha256_freq = 300000000,
+ .sha384_freq = 300000000,
+ .sha512_freq = 300000000,
};
static struct tegra_se_chipdata tegra11_se_chipdata = {
.rsa_supported = true,
.cprng_supported = false,
.drbg_supported = true,
+ .aes_freq = 150000000,
+ .rng_freq = 150000000,
+ .sha1_freq = 200000000,
+ .sha224_freq = 250000000,
+ .sha256_freq = 250000000,
+ .sha384_freq = 150000000,
+ .sha512_freq = 150000000,
+ .rsa_freq = 350000000,
};