From 04dd17822334871b23ea2862f7798fb0e0007777 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 11 May 2024 08:53:19 +0000
Subject: [PATCH] change otg to host mode
---
u-boot/drivers/crypto/rockchip/crypto_v2.c | 226 +++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 166 insertions(+), 60 deletions(-)
diff --git a/u-boot/drivers/crypto/rockchip/crypto_v2.c b/u-boot/drivers/crypto/rockchip/crypto_v2.c
index 86226fe..e2135a7 100644
--- a/u-boot/drivers/crypto/rockchip/crypto_v2.c
+++ b/u-boot/drivers/crypto/rockchip/crypto_v2.c
@@ -8,6 +8,7 @@
#include <crypto.h>
#include <dm.h>
#include <asm/io.h>
+#include <clk-uclass.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clock.h>
#include <rockchip/crypto_hash_cache.h>
@@ -54,6 +55,7 @@
char *clocks;
u32 *frequencies;
u32 nclocks;
+ u32 freq_nclocks;
u32 length;
struct rk_hash_ctx *hw_ctx;
struct rk_crypto_soc_data *soc_data;
@@ -217,6 +219,43 @@
for (i = 0; i < tag_len / 4; i++, chn_base += 4)
word2byte_be(crypto_read(chn_base), tag + 4 * i);
+}
+
+static int rk_crypto_do_enable_clk(struct udevice *dev, int enable)
+{
+ struct rockchip_crypto_priv *priv = dev_get_priv(dev);
+ struct clk clk;
+ int i, ret;
+
+ for (i = 0; i < priv->nclocks; i++) {
+ ret = clk_get_by_index(dev, i, &clk);
+ if (ret < 0) {
+ printf("Failed to get clk index %d, ret=%d\n", i, ret);
+ return ret;
+ }
+
+ if (enable)
+ ret = clk_enable(&clk);
+ else
+ ret = clk_disable(&clk);
+ if (ret < 0 && ret != -ENOSYS) {
+ printf("Failed to enable(%d) clk(%ld): ret=%d\n",
+ enable, clk.id, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int rk_crypto_enable_clk(struct udevice *dev)
+{
+ return rk_crypto_do_enable_clk(dev, 1);
+}
+
+static int rk_crypto_disable_clk(struct udevice *dev)
+{
+ return rk_crypto_do_enable_clk(dev, 0);
}
static u32 crypto_v3_dynamic_cap(void)
@@ -397,7 +436,7 @@
if (!(*started_flag)) {
lli->user_define |=
- (LLI_USER_STRING_START | LLI_USER_CPIHER_START);
+ (LLI_USER_STRING_START | LLI_USER_CIPHER_START);
crypto_write((u32)virt_to_phys(lli), CRYPTO_DMA_LLI_ADDR);
crypto_write((CRYPTO_HASH_ENABLE << CRYPTO_WRITE_MASK_SHIFT) |
CRYPTO_HASH_ENABLE, CRYPTO_HASH_CTL);
@@ -520,6 +559,7 @@
{
struct rockchip_crypto_priv *priv = dev_get_priv(dev);
struct rk_hash_ctx *hash_ctx = priv->hw_ctx;
+ int ret = 0;
if (!ctx)
return -EINVAL;
@@ -535,7 +575,12 @@
if (!hash_ctx->hash_cache)
return -EFAULT;
- return rk_hash_init(hash_ctx, ctx->algo);
+ rk_crypto_enable_clk(dev);
+ ret = rk_hash_init(hash_ctx, ctx->algo);
+ if (ret)
+ rk_crypto_disable_clk(dev);
+
+ return ret;
}
static int rockchip_crypto_sha_update(struct udevice *dev,
@@ -545,8 +590,10 @@
int ret, i;
u8 *p;
- if (!len)
- return -EINVAL;
+ if (!len) {
+ ret = -EINVAL;
+ goto exit;
+ }
p = (u8 *)input;
@@ -560,6 +607,9 @@
ret = rk_hash_update(priv->hw_ctx, p, len % HASH_UPDATE_LIMIT);
exit:
+ if (ret)
+ rk_crypto_disable_clk(dev);
+
return ret;
}
@@ -583,6 +633,8 @@
exit:
hw_hash_clean_ctx(priv->hw_ctx);
+ rk_crypto_disable_clk(dev);
+
return ret;
}
@@ -614,6 +666,7 @@
{
struct rockchip_crypto_priv *priv = dev_get_priv(dev);
struct rk_hash_ctx *hash_ctx = priv->hw_ctx;
+ int ret = 0;
if (!ctx)
return -EINVAL;
@@ -629,7 +682,12 @@
if (!hash_ctx->hash_cache)
return -EFAULT;
- return rk_hmac_init(priv->hw_ctx, ctx->algo, key, key_len);
+ rk_crypto_enable_clk(dev);
+ ret = rk_hmac_init(priv->hw_ctx, ctx->algo, key, key_len);
+ if (ret)
+ rk_crypto_disable_clk(dev);
+
+ return ret;
}
static int rockchip_crypto_hmac_update(struct udevice *dev,
@@ -763,6 +821,11 @@
{
u32 i;
+ if (aad_len == 0) {
+ *padding_size = 0;
+ return;
+ }
+
i = aad_len < (0x10000 - 0x100) ? 2 : 6;
if (i == 2) {
@@ -779,7 +842,7 @@
*padding_size = i;
}
-static int ccm_compose_aad_iv(u8 *aad_iv, u32 data_len, u32 tag_size)
+static int ccm_compose_aad_iv(u8 *aad_iv, u32 data_len, u32 aad_len, u32 tag_size)
{
aad_iv[0] |= ((u8)(((tag_size - 2) / 2) & 7) << 3);
@@ -788,7 +851,8 @@
aad_iv[14] = (u8)(data_len >> 8);
aad_iv[15] = (u8)data_len;
- aad_iv[0] |= 0x40; //set aad flag
+ if (aad_len)
+ aad_iv[0] |= 0x40; //set aad flag
return 0;
}
@@ -925,12 +989,14 @@
data_desc->dma_ctrl |= LLI_DMA_CTRL_DST_DONE;
}
+ data_desc->user_define = LLI_USER_CIPHER_START |
+ LLI_USER_STRING_START |
+ LLI_USER_STRING_LAST |
+ (key_chn << 4);
+ crypto_write((u32)virt_to_phys(data_desc), CRYPTO_DMA_LLI_ADDR);
+
if (rk_mode == RK_MODE_CCM || rk_mode == RK_MODE_GCM) {
u32 aad_tmp_len = 0;
-
- data_desc->user_define = LLI_USER_STRING_START |
- LLI_USER_STRING_LAST |
- (key_chn << 4);
aad_desc = align_malloc(sizeof(*aad_desc), LLI_ADDR_ALIGN_SIZE);
if (!aad_desc)
@@ -938,7 +1004,7 @@
memset(aad_desc, 0x00, sizeof(*aad_desc));
aad_desc->next_addr = (u32)virt_to_phys(data_desc);
- aad_desc->user_define = LLI_USER_CPIHER_START |
+ aad_desc->user_define = LLI_USER_CIPHER_START |
LLI_USER_STRING_START |
LLI_USER_STRING_LAST |
LLI_USER_STRING_AAD |
@@ -958,12 +1024,15 @@
if (!aad_tmp)
goto exit;
- /* read iv data from reg */
- get_iv_reg(key_chn, aad_tmp, AES_BLOCK_SIZE);
- ccm_compose_aad_iv(aad_tmp, tmp_len, tag_len);
- memcpy(aad_tmp + AES_BLOCK_SIZE, padding, padding_size);
+ /* clear last block */
memset(aad_tmp + aad_tmp_len - AES_BLOCK_SIZE,
0x00, AES_BLOCK_SIZE);
+
+ /* read iv data from reg */
+ get_iv_reg(key_chn, aad_tmp, AES_BLOCK_SIZE);
+ ccm_compose_aad_iv(aad_tmp, tmp_len, aad_len, tag_len);
+ memcpy(aad_tmp + AES_BLOCK_SIZE, padding, padding_size);
+
memcpy(aad_tmp + AES_BLOCK_SIZE + padding_size,
aad, aad_len);
} else {
@@ -985,15 +1054,15 @@
aad_desc->src_addr = (u32)virt_to_phys(aad_tmp);
aad_desc->src_len = aad_tmp_len;
- crypto_write((u32)virt_to_phys(aad_desc), CRYPTO_DMA_LLI_ADDR);
- cache_op_inner(DCACHE_AREA_CLEAN, aad_tmp, aad_tmp_len);
- cache_op_inner(DCACHE_AREA_CLEAN, aad_desc, sizeof(*aad_desc));
- } else {
- data_desc->user_define = LLI_USER_CPIHER_START |
- LLI_USER_STRING_START |
- LLI_USER_STRING_LAST |
- (key_chn << 4);
- crypto_write((u32)virt_to_phys(data_desc), CRYPTO_DMA_LLI_ADDR);
+
+ if (aad_tmp_len) {
+ data_desc->user_define = LLI_USER_STRING_START |
+ LLI_USER_STRING_LAST |
+ (key_chn << 4);
+ crypto_write((u32)virt_to_phys(aad_desc), CRYPTO_DMA_LLI_ADDR);
+ cache_op_inner(DCACHE_AREA_CLEAN, aad_tmp, aad_tmp_len);
+ cache_op_inner(DCACHE_AREA_CLEAN, aad_desc, sizeof(*aad_desc));
+ }
}
cache_op_inner(DCACHE_AREA_CLEAN, data_desc, sizeof(*data_desc));
@@ -1175,21 +1244,29 @@
int rockchip_crypto_cipher(struct udevice *dev, cipher_context *ctx,
const u8 *in, u8 *out, u32 len, bool enc)
{
+ int ret;
+
+ rk_crypto_enable_clk(dev);
+
switch (ctx->algo) {
case CRYPTO_DES:
- return rk_crypto_des(dev, ctx->mode, ctx->key, ctx->key_len,
- ctx->iv, in, out, len, enc);
+ ret = rk_crypto_des(dev, ctx->mode, ctx->key, ctx->key_len,
+ ctx->iv, in, out, len, enc);
case CRYPTO_AES:
- return rk_crypto_aes(dev, ctx->mode,
- ctx->key, ctx->twk_key, ctx->key_len,
- ctx->iv, ctx->iv_len, in, out, len, enc);
+ ret = rk_crypto_aes(dev, ctx->mode,
+ ctx->key, ctx->twk_key, ctx->key_len,
+ ctx->iv, ctx->iv_len, in, out, len, enc);
case CRYPTO_SM4:
- return rk_crypto_sm4(dev, ctx->mode,
- ctx->key, ctx->twk_key, ctx->key_len,
- ctx->iv, ctx->iv_len, in, out, len, enc);
+ ret = rk_crypto_sm4(dev, ctx->mode,
+ ctx->key, ctx->twk_key, ctx->key_len,
+ ctx->iv, ctx->iv_len, in, out, len, enc);
default:
- return -EINVAL;
+ ret = -EINVAL;
}
+
+ rk_crypto_disable_clk(dev);
+
+ return ret;
}
int rk_crypto_mac(struct udevice *dev, u32 algo, u32 mode,
@@ -1223,8 +1300,16 @@
int rockchip_crypto_mac(struct udevice *dev, cipher_context *ctx,
const u8 *in, u32 len, u8 *tag)
{
- return rk_crypto_mac(dev, ctx->algo, ctx->mode,
- ctx->key, ctx->key_len, in, len, tag);
+ int ret = 0;
+
+ rk_crypto_enable_clk(dev);
+
+ ret = rk_crypto_mac(dev, ctx->algo, ctx->mode,
+ ctx->key, ctx->key_len, in, len, tag);
+
+ rk_crypto_disable_clk(dev);
+
+ return ret;
}
int rk_crypto_ae(struct udevice *dev, u32 algo, u32 mode,
@@ -1236,6 +1321,9 @@
int ret;
if (!IS_AE_MODE(rk_mode))
+ return -EINVAL;
+
+ if (len == 0)
return -EINVAL;
if (algo != CRYPTO_AES && algo != CRYPTO_SM4)
@@ -1261,9 +1349,17 @@
u8 *out, u8 *tag)
{
- return rk_crypto_ae(dev, ctx->algo, ctx->mode, ctx->key, ctx->key_len,
- ctx->iv, ctx->iv_len, in, len,
- aad, aad_len, out, tag);
+ int ret = 0;
+
+ rk_crypto_enable_clk(dev);
+
+ ret = rk_crypto_ae(dev, ctx->algo, ctx->mode, ctx->key, ctx->key_len,
+ ctx->iv, ctx->iv_len, in, len,
+ aad, aad_len, out, tag);
+
+ rk_crypto_disable_clk(dev);
+
+ return ret;
}
#endif
@@ -1312,9 +1408,11 @@
if (ret)
goto exit;
+ rk_crypto_enable_clk(dev);
ret = rk_exptmod_np(mpa_m, mpa_e, mpa_n, mpa_c, mpa_result);
if (!ret)
memcpy(output, mpa_result->d, BITS2BYTE(n_bits));
+ rk_crypto_disable_clk(dev);
exit:
rk_mpa_free(&mpa_m);
@@ -1378,7 +1476,7 @@
if (!priv->clocks)
return -ENOMEM;
- priv->nclocks = len / sizeof(u32);
+ priv->nclocks = len / (2 * sizeof(u32));
if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks,
priv->nclocks)) {
printf("Can't read \"clocks\" property\n");
@@ -1386,24 +1484,19 @@
goto exit;
}
- if (!dev_read_prop(dev, "clock-frequency", &len)) {
- printf("Can't find \"clock-frequency\" property\n");
- ret = -EINVAL;
- goto exit;
- }
-
- priv->frequencies = malloc(len);
- if (!priv->frequencies) {
- ret = -ENOMEM;
- goto exit;
- }
-
- priv->nclocks = len / sizeof(u32);
- if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies,
- priv->nclocks)) {
- printf("Can't read \"clock-frequency\" property\n");
- ret = -EINVAL;
- goto exit;
+ if (dev_read_prop(dev, "clock-frequency", &len)) {
+ priv->frequencies = malloc(len);
+ if (!priv->frequencies) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ priv->freq_nclocks = len / sizeof(u32);
+ if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies,
+ priv->freq_nclocks)) {
+ printf("Can't read \"clock-frequency\" property\n");
+ ret = -EINVAL;
+ goto exit;
+ }
}
return 0;
@@ -1423,10 +1516,15 @@
struct clk clk;
int i, ret;
- if (!priv->clocks && priv->nclocks == 0)
+ /* use standard "assigned-clock-rates" props */
+ if (dev_read_size(dev, "assigned-clock-rates") > 0)
+ return clk_set_defaults(dev);
+
+ /* use "clock-frequency" props */
+ if (priv->freq_nclocks == 0)
return 0;
- for (i = 0; i < priv->nclocks; i++) {
+ for (i = 0; i < priv->freq_nclocks; i++) {
ret = clk_get_by_index(dev, i, &clk);
if (ret < 0) {
printf("Failed to get clk index %d, ret=%d\n", i, ret);
@@ -1465,7 +1563,11 @@
if (ret)
return ret;
+ rk_crypto_enable_clk(dev);
+
hw_crypto_reset();
+
+ rk_crypto_disable_clk(dev);
return 0;
}
@@ -1557,6 +1659,10 @@
.compatible = "rockchip,crypto-v3",
.data = (ulong)&soc_data_cryptov3
},
+ {
+ .compatible = "rockchip,crypto-v4",
+ .data = (ulong)&soc_data_cryptov3 /* reuse crypto v3 config */
+ },
{ }
};
--
Gitblit v1.6.2