From 9df731a176aab8e03b984b681b1bea01ccff6644 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 07:23:06 +0000
Subject: [PATCH] rk3568 rt uboot init

---
 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