2022-04-26 00:21:05

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 00/33] crypto: rockchip: permit to pass self-tests

Hello

The rockchip crypto driver is broken and do not pass self-tests.
This serie's goal is to permit to become usable and pass self-tests.

This whole serie is tested on a rk3328-rock64, rk3288-miqi and
rk3399-khadas-edge-v with selftests (with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y)

Regards

Changes since v1:
- select CRYPTO_ENGINE
- forgot to free fallbacks TFMs
- fixed kernel test robots warning
- add the PM patch

Changes since v2:
- Added DMA clock back to 3288 since it dont work without it
- fallback needed to select CBC and ECB configs
- Added support for rk3399
- Added more patch (style, read_poll_timeout)

Changes since v3:
- full rewrite of support for RK3399
- splited dt-binding patch in two

Changes since v4:
- Another full rewrite of support for RK3399
- Fixed dt-binding from Krzysztof Kozlowski's comments
- Use readl_poll_timeout() instead of read_poll_timeout()
- Rewrite the fallback SG tests

Changes since v5:
- fixed errors in DT binding patch

Corentin Labbe (33):
crypto: rockchip: use dev_err for error message about interrupt
crypto: rockchip: do not use uninitialized variable
crypto: rockchip: do not do custom power management
crypto: rockchip: fix privete/private typo
crypto: rockchip: do not store mode globally
crypto: rockchip: add fallback for cipher
crypto: rockchip: add fallback for ahash
crypto: rockchip: better handle cipher key
crypto: rockchip: remove non-aligned handling
crypto: rockchip: rework by using crypto_engine
crypto: rockchip: rewrite type
crypto: rockchip: add debugfs
crypto: rockchip: introduce PM
crypto: rockchip: handle reset also in PM
crypto: rockchip: use clk_bulk to simplify clock management
crypto: rockchip: add myself as maintainer
crypto: rockchip: use read_poll_timeout
crypto: rockchip: fix style issue
crypto: rockchip: add support for rk3328
crypto: rockchip: rename ablk functions to cipher
crypto: rockchip: rework rk_handle_req function
crypto: rockchip: use a rk_crypto_info variable instead of lot of
indirection
crypto: rockchip: use the rk_crypto_info given as parameter
dt-bindings: crypto: convert rockchip-crypto to YAML
dt-bindings: crypto: rockchip: convert to new driver bindings
clk: rk3399: use proper crypto0 name
arm64: dts: rockchip: add rk3328 crypto node
arm64: dts: rockchip: rk3399: add crypto node
crypto: rockchip: store crypto_info in request context
crypto: rockchip: Check for clocks numbers and their frequencies
crypto: rockchip: rk_ahash_reg_init use crypto_info from parameter
crypto: rockchip: permit to have more than one reset
crypto: rockchip: Add support for RK3399

.../crypto/rockchip,rk3288-crypto.yaml | 133 +++++
.../bindings/crypto/rockchip-crypto.txt | 28 -
MAINTAINERS | 7 +
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 11 +
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 20 +
drivers/crypto/Kconfig | 15 +
drivers/crypto/rockchip/rk3288_crypto.c | 511 ++++++++--------
drivers/crypto/rockchip/rk3288_crypto.h | 107 ++--
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 267 +++++----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 543 ++++++++++--------
include/dt-bindings/clock/rk3399-cru.h | 6 +-
11 files changed, 953 insertions(+), 695 deletions(-)
create mode 100644 Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
delete mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt

--
2.35.1


2022-04-26 01:59:12

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

The latest addition to the rockchip crypto driver need to update the
driver bindings.

Signed-off-by: Corentin Labbe <[email protected]>
---
.../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
1 file changed, 77 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
index 8a219d439d02..ad604d7e4bc0 100644
--- a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
@@ -13,6 +13,8 @@ properties:
compatible:
enum:
- rockchip,rk3288-crypto
+ - rockchip,rk3328-crypto
+ - rockchip,rk3399-crypto

reg:
maxItems: 1
@@ -21,21 +23,88 @@ properties:
maxItems: 1

clocks:
+ minItems: 3
maxItems: 4

clock-names:
- items:
- - const: aclk
- - const: hclk
- - const: sclk
- - const: apb_pclk
+ minItems: 3
+ maxItems: 4

resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 3

reset-names:
- items:
- - const: crypto-rst
+ minItems: 1
+ maxItems: 3
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3288-crypto
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ clock-names:
+ items:
+ - const: "aclk"
+ - const: "hclk"
+ - const: "sclk"
+ - const: "apb_pclk"
+ minItems: 4
+ resets:
+ maxItems: 1
+ reset-names:
+ items:
+ - const: "crypto-rst"
+ maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3328-crypto
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: "hclk_master"
+ - const: "hclk_slave"
+ - const: "sclk"
+ maxItems: 3
+ resets:
+ maxItems: 1
+ reset-names:
+ items:
+ - const: "crypto-rst"
+ maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3399-crypto
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: "hclk_master"
+ - const: "hclk_slave"
+ - const: "sclk"
+ maxItems: 3
+ resets:
+ minItems: 3
+ reset-names:
+ items:
+ - const: "rst_master"
+ - const: "rst_slave"
+ - const: "crypto-rst"
+ minItems: 3

required:
- compatible
--
2.35.1

2022-04-26 02:02:45

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 26/33] clk: rk3399: use proper crypto0 name

RK3399 has 2 crypto instance, named crypto0 and crypto1 in the TRM.
Only reset for crypto1 is correctly named, but crypto0 is not.
Since nobody use them , add a 0 to be consistent with the TRM and crypto1 entries.

Acked-by: Rob Herring <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
include/dt-bindings/clock/rk3399-cru.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 44e0a319f077..39169d94a44e 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -547,8 +547,8 @@
#define SRST_H_PERILP0 171
#define SRST_H_PERILP0_NOC 172
#define SRST_ROM 173
-#define SRST_CRYPTO_S 174
-#define SRST_CRYPTO_M 175
+#define SRST_CRYPTO0_S 174
+#define SRST_CRYPTO0_M 175

/* cru_softrst_con11 */
#define SRST_P_DCF 176
@@ -556,7 +556,7 @@
#define SRST_CM0S 178
#define SRST_CM0S_DBG 179
#define SRST_CM0S_PO 180
-#define SRST_CRYPTO 181
+#define SRST_CRYPTO0 181
#define SRST_P_PERILP1_SGRF 182
#define SRST_P_PERILP1_GRF 183
#define SRST_CRYPTO1_S 184
--
2.35.1

2022-04-26 02:02:53

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 22/33] crypto: rockchip: use a rk_crypto_info variable instead of lot of indirection

Instead of using lot of ctx->dev->xx indirections, use an intermediate
variable for rk_crypto_info.
This will help later, when 2 different rk_crypto_info would be used.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 23 +++++++-----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 37 ++++++++++---------
2 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index fae779d73c84..636dbcde0ca3 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -226,9 +226,10 @@ static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct rk_crypto_info *rkc = tctx->dev;
int ret;

- ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
+ ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
if (ret <= 0)
return -EINVAL;

@@ -243,8 +244,9 @@ static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct rk_crypto_info *rkc = tctx->dev;

- dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
+ dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
return 0;
}

@@ -257,6 +259,7 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
struct scatterlist *sg = areq->src;
+ struct rk_crypto_info *rkc = tctx->dev;
int err = 0;
int i;
u32 v;
@@ -283,13 +286,13 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
rk_ahash_reg_init(areq);

while (sg) {
- reinit_completion(&tctx->dev->complete);
- tctx->dev->status = 0;
- crypto_ahash_dma_start(tctx->dev, sg);
- wait_for_completion_interruptible_timeout(&tctx->dev->complete,
+ reinit_completion(&rkc->complete);
+ rkc->status = 0;
+ crypto_ahash_dma_start(rkc, sg);
+ wait_for_completion_interruptible_timeout(&rkc->complete,
msecs_to_jiffies(2000));
- if (!tctx->dev->status) {
- dev_err(tctx->dev->dev, "DMA timeout\n");
+ if (!rkc->status) {
+ dev_err(rkc->dev, "DMA timeout\n");
err = -EFAULT;
goto theend;
}
@@ -306,10 +309,10 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
* efficiency, and make it response quickly when dma
* complete.
*/
- readl_poll_timeout(tctx->dev->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000);
+ readl_poll_timeout(rkc->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000);

for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
- v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
+ v = readl(rkc->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
put_unaligned_le32(v, areq->result + i * 4);
}

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 3187869c4c68..6a1bea98fded 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -303,6 +303,7 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
unsigned int todo;
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+ struct rk_crypto_info *rkc = ctx->dev;

algt->stat_req++;

@@ -330,49 +331,49 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0);
}
if (sgs == sgd) {
- err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ err = dma_map_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL);
if (err <= 0) {
err = -EINVAL;
goto theend_iv;
}
} else {
- err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
+ err = dma_map_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE);
if (err <= 0) {
err = -EINVAL;
goto theend_iv;
}
- err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ err = dma_map_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE);
if (err <= 0) {
err = -EINVAL;
goto theend_sgs;
}
}
err = 0;
- rk_cipher_hw_init(ctx->dev, areq);
+ rk_cipher_hw_init(rkc, areq);
if (ivsize) {
if (ivsize == DES_BLOCK_SIZE)
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
+ memcpy_toio(rkc->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
else
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
+ memcpy_toio(rkc->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
}
- reinit_completion(&ctx->dev->complete);
- ctx->dev->status = 0;
+ reinit_completion(&rkc->complete);
+ rkc->status = 0;

todo = min(sg_dma_len(sgs), len);
len -= todo;
- crypto_dma_start(ctx->dev, sgs, sgd, todo / 4);
- wait_for_completion_interruptible_timeout(&ctx->dev->complete,
+ crypto_dma_start(rkc, sgs, sgd, todo / 4);
+ wait_for_completion_interruptible_timeout(&rkc->complete,
msecs_to_jiffies(2000));
- if (!ctx->dev->status) {
- dev_err(ctx->dev->dev, "DMA timeout\n");
+ if (!rkc->status) {
+ dev_err(rkc->dev, "DMA timeout\n");
err = -EFAULT;
goto theend;
}
if (sgs == sgd) {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL);
} else {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
- dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE);
}
if (rctx->mode & RK_CRYPTO_DEC) {
memcpy(iv, biv, ivsize);
@@ -405,10 +406,10 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)

theend_sgs:
if (sgs == sgd) {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL);
} else {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
- dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE);
}
theend_iv:
return err;
--
2.35.1

2022-04-26 04:36:51

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 27/33] arm64: dts: rockchip: add rk3328 crypto node

rk3328 has a crypto IP handled by the rk3288 crypto driver so adds a
node for it.

Signed-off-by: Corentin Labbe <[email protected]>
---
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index b822533dc7f1..c23fa985e66d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -1007,6 +1007,17 @@ gic: interrupt-controller@ff811000 {
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};

+ crypto: crypto@ff060000 {
+ compatible = "rockchip,rk3328-crypto";
+ reg = <0x0 0xff060000 0x0 0x4000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_CRYPTO_MST>, <&cru HCLK_CRYPTO_SLV>,
+ <&cru SCLK_CRYPTO>;
+ clock-names = "hclk_master", "hclk_slave", "sclk";
+ resets = <&cru SRST_CRYPTO>;
+ reset-names = "crypto-rst";
+ };
+
pinctrl: pinctrl {
compatible = "rockchip,rk3328-pinctrl";
rockchip,grf = <&grf>;
--
2.35.1

2022-04-26 07:08:49

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 16/33] crypto: rockchip: add myself as maintainer

Nobody is set as maintainer of rockchip crypto, I propose to do it as I
have already reworked lot of this code.

Signed-off-by: Corentin Labbe <[email protected]>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6157e706ed02..1f3bd9b5827e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17005,6 +17005,13 @@ F: Documentation/ABI/*/sysfs-driver-hid-roccat*
F: drivers/hid/hid-roccat*
F: include/linux/hid-roccat*

+ROCKCHIP CRYPTO DRIVERS
+M: Corentin Labbe <[email protected]>
+L: [email protected]
+S: Maintained
+F: Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
+F: drivers/crypto/rockchip/
+
ROCKCHIP I2S TDM DRIVER
M: Nicolas Frattaroli <[email protected]>
L: [email protected]
--
2.35.1

2022-04-26 07:39:39

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 01/33] crypto: rockchip: use dev_err for error message about interrupt

Interrupt is mandatory so the message should be printed as error.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 35d73061d156..45cc5f766788 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -371,8 +371,7 @@ static int rk_crypto_probe(struct platform_device *pdev)

crypto_info->irq = platform_get_irq(pdev, 0);
if (crypto_info->irq < 0) {
- dev_warn(crypto_info->dev,
- "control Interrupt is not available.\n");
+ dev_err(&pdev->dev, "control Interrupt is not available.\n");
err = crypto_info->irq;
goto err_crypto;
}
--
2.35.1

2022-04-26 07:50:49

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 11/33] crypto: rockchip: rewrite type

Instead of using a custom type for classify algorithms, let's just use
already defined ones.
And let's made a bit more verbose about what is registered.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 26 +++++++++++++------
drivers/crypto/rockchip/rk3288_crypto.h | 7 +----
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 6 ++---
.../crypto/rockchip/rk3288_crypto_skcipher.c | 12 ++++-----
4 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 1afb65eee6c9..8f9664acc78d 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -102,12 +102,22 @@ static int rk_crypto_register(struct rk_crypto_info *crypto_info)

for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
rk_cipher_algs[i]->dev = crypto_info;
- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
- err = crypto_register_skcipher(
- &rk_cipher_algs[i]->alg.skcipher);
- else
- err = crypto_register_ahash(
- &rk_cipher_algs[i]->alg.hash);
+ switch (rk_cipher_algs[i]->type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ dev_info(crypto_info->dev, "Register %s as %s\n",
+ rk_cipher_algs[i]->alg.skcipher.base.cra_name,
+ rk_cipher_algs[i]->alg.skcipher.base.cra_driver_name);
+ err = crypto_register_skcipher(&rk_cipher_algs[i]->alg.skcipher);
+ break;
+ case CRYPTO_ALG_TYPE_AHASH:
+ dev_info(crypto_info->dev, "Register %s as %s\n",
+ rk_cipher_algs[i]->alg.hash.halg.base.cra_name,
+ rk_cipher_algs[i]->alg.hash.halg.base.cra_driver_name);
+ err = crypto_register_ahash(&rk_cipher_algs[i]->alg.hash);
+ break;
+ default:
+ dev_err(crypto_info->dev, "unknown algorithm\n");
+ }
if (err)
goto err_cipher_algs;
}
@@ -115,7 +125,7 @@ static int rk_crypto_register(struct rk_crypto_info *crypto_info)

err_cipher_algs:
for (k = 0; k < i; k++) {
- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+ if (rk_cipher_algs[i]->type == CRYPTO_ALG_TYPE_SKCIPHER)
crypto_unregister_skcipher(&rk_cipher_algs[k]->alg.skcipher);
else
crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash);
@@ -128,7 +138,7 @@ static void rk_crypto_unregister(void)
unsigned int i;

for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+ if (rk_cipher_algs[i]->type == CRYPTO_ALG_TYPE_SKCIPHER)
crypto_unregister_skcipher(&rk_cipher_algs[i]->alg.skcipher);
else
crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash);
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 65ed645e0168..d924ea17402a 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -232,18 +232,13 @@ struct rk_cipher_rctx {
struct skcipher_request fallback_req; // keep at the end
};

-enum alg_type {
- ALG_TYPE_HASH,
- ALG_TYPE_CIPHER,
-};
-
struct rk_crypto_tmp {
+ u32 type;
struct rk_crypto_info *dev;
union {
struct skcipher_alg skcipher;
struct ahash_alg hash;
} alg;
- enum alg_type type;
};

extern struct rk_crypto_tmp rk_ecb_aes_alg;
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index edd40e16a3f0..d08e2438d356 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -352,7 +352,7 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
}

struct rk_crypto_tmp rk_ahash_sha1 = {
- .type = ALG_TYPE_HASH,
+ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
.init = rk_ahash_init,
.update = rk_ahash_update,
@@ -382,7 +382,7 @@ struct rk_crypto_tmp rk_ahash_sha1 = {
};

struct rk_crypto_tmp rk_ahash_sha256 = {
- .type = ALG_TYPE_HASH,
+ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
.init = rk_ahash_init,
.update = rk_ahash_update,
@@ -412,7 +412,7 @@ struct rk_crypto_tmp rk_ahash_sha256 = {
};

struct rk_crypto_tmp rk_ahash_md5 = {
- .type = ALG_TYPE_HASH,
+ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
.init = rk_ahash_init,
.update = rk_ahash_update,
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 67a7e05d5ae3..1ed297f5d809 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -468,7 +468,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(aes)",
.base.cra_driver_name = "ecb-aes-rk",
@@ -490,7 +490,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
};

struct rk_crypto_tmp rk_cbc_aes_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "cbc(aes)",
.base.cra_driver_name = "cbc-aes-rk",
@@ -513,7 +513,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
};

struct rk_crypto_tmp rk_ecb_des_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(des)",
.base.cra_driver_name = "ecb-des-rk",
@@ -535,7 +535,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
};

struct rk_crypto_tmp rk_cbc_des_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "cbc(des)",
.base.cra_driver_name = "cbc-des-rk",
@@ -558,7 +558,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
};

struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(des3_ede)",
.base.cra_driver_name = "ecb-des3-ede-rk",
@@ -580,7 +580,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
};

struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "cbc(des3_ede)",
.base.cra_driver_name = "cbc-des3-ede-rk",
--
2.35.1

2022-04-26 08:34:31

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 05/33] crypto: rockchip: do not store mode globally

Storing the mode globally does not work if 2 requests are handled in the
same time.
We should store it in a request context.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.h | 5 +-
.../crypto/rockchip/rk3288_crypto_skcipher.c | 58 ++++++++++++-------
2 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 656d6795d400..c919d9a43a08 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -245,10 +245,13 @@ struct rk_ahash_rctx {
struct rk_cipher_ctx {
struct rk_crypto_info *dev;
unsigned int keylen;
- u32 mode;
u8 iv[AES_BLOCK_SIZE];
};

+struct rk_cipher_rctx {
+ u32 mode;
+};
+
enum alg_type {
ALG_TYPE_HASH,
ALG_TYPE_CIPHER,
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 8c44a19eab75..bbd0bf52bf07 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -76,9 +76,10 @@ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_ECB_MODE;
+ rctx->mode = RK_CRYPTO_AES_ECB_MODE;
return rk_handle_req(dev, req);
}

@@ -86,9 +87,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -96,9 +98,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_CBC_MODE;
+ rctx->mode = RK_CRYPTO_AES_CBC_MODE;
return rk_handle_req(dev, req);
}

@@ -106,9 +109,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -116,9 +120,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = 0;
+ rctx->mode = 0;
return rk_handle_req(dev, req);
}

@@ -126,9 +131,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -136,9 +142,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
+ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
return rk_handle_req(dev, req);
}

@@ -146,9 +153,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -156,9 +164,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT;
+ rctx->mode = RK_CRYPTO_TDES_SELECT;
return rk_handle_req(dev, req);
}

@@ -166,9 +175,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -176,9 +186,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
+ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
return rk_handle_req(dev, req);
}

@@ -186,9 +197,10 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
+ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}
@@ -199,6 +211,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
u32 ivsize, block, conf_reg = 0;

@@ -206,22 +219,22 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
ivsize = crypto_skcipher_ivsize(cipher);

if (block == DES_BLOCK_SIZE) {
- ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+ rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
RK_CRYPTO_TDES_BYTESWAP_KEY |
RK_CRYPTO_TDES_BYTESWAP_IV;
- CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
+ CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
conf_reg = RK_CRYPTO_DESSEL;
} else {
- ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+ rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
RK_CRYPTO_AES_KEY_CHANGE |
RK_CRYPTO_AES_BYTESWAP_KEY |
RK_CRYPTO_AES_BYTESWAP_IV;
if (ctx->keylen == AES_KEYSIZE_192)
- ctx->mode |= RK_CRYPTO_AES_192BIT_key;
+ rctx->mode |= RK_CRYPTO_AES_192BIT_key;
else if (ctx->keylen == AES_KEYSIZE_256)
- ctx->mode |= RK_CRYPTO_AES_256BIT_key;
- CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
+ rctx->mode |= RK_CRYPTO_AES_256BIT_key;
+ CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
}
conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
@@ -246,6 +259,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
struct skcipher_request *req =
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
u32 ivsize = crypto_skcipher_ivsize(tfm);
u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
@@ -254,7 +268,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
/* Store the iv that need to be updated in chain mode.
* And update the IV buffer to contain the next IV for decryption mode.
*/
- if (ctx->mode & RK_CRYPTO_DEC) {
+ if (rctx->mode & RK_CRYPTO_DEC) {
memcpy(ctx->iv, src_last_blk, ivsize);
sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
ivsize, dev->total - ivsize);
@@ -294,11 +308,12 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
struct skcipher_request *req =
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
u32 ivsize = crypto_skcipher_ivsize(tfm);

/* Update the IV buffer to contain the next IV for encryption mode. */
- if (!(ctx->mode & RK_CRYPTO_DEC)) {
+ if (!(rctx->mode & RK_CRYPTO_DEC)) {
if (dev->aligned) {
memcpy(req->iv, sg_virt(dev->sg_dst) +
dev->sg_dst->length - ivsize, ivsize);
@@ -314,11 +329,12 @@ static void rk_update_iv(struct rk_crypto_info *dev)
struct skcipher_request *req =
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
u32 ivsize = crypto_skcipher_ivsize(tfm);
u8 *new_iv = NULL;

- if (ctx->mode & RK_CRYPTO_DEC) {
+ if (rctx->mode & RK_CRYPTO_DEC) {
new_iv = ctx->iv;
} else {
new_iv = page_address(sg_page(dev->sg_dst)) +
--
2.35.1

2022-04-26 08:38:03

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 33/33] crypto: rockchip: Add support for RK3399

The RK3399 has 2 rk3288 compatible crypto device named crypto0 and
crypto1. The only difference is lack of RSA in crypto1.

We need to add driver support for 2 parallel instance as only one need
to register crypto algorithms.
Then the driver will round robin each request on each device.

For avoiding complexity (device bringup after a TFM is created), PM is
modified to be handled per request.
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 92 +++++++++++++++----
drivers/crypto/rockchip/rk3288_crypto.h | 25 +++--
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 37 ++++----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 37 ++++----
4 files changed, 123 insertions(+), 68 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 9ba9b9e433c4..baf015f6707b 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -19,6 +19,23 @@
#include <linux/crypto.h>
#include <linux/reset.h>

+static struct rockchip_ip rocklist = {
+ .dev_list = LIST_HEAD_INIT(rocklist.dev_list),
+ .lock = __SPIN_LOCK_UNLOCKED(rocklist.lock),
+};
+
+struct rk_crypto_info *get_rk_crypto(void)
+{
+ struct rk_crypto_info *first;
+
+ spin_lock(&rocklist.lock);
+ first = list_first_entry_or_null(&rocklist.dev_list,
+ struct rk_crypto_info, list);
+ list_rotate_left(&rocklist.dev_list);
+ spin_unlock(&rocklist.lock);
+ return first;
+}
+
static const struct rk_variant rk3288_variant = {
.num_clks = 4,
.rkclks = {
@@ -30,6 +47,10 @@ static const struct rk_variant rk3328_variant = {
.num_clks = 3,
};

+static const struct rk_variant rk3399_variant = {
+ .num_clks = 3,
+};
+
static int rk_crypto_get_clks(struct rk_crypto_info *dev)
{
int i, j, err;
@@ -83,8 +104,8 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
}

/*
- * Power management strategy: The device is suspended unless a TFM exists for
- * one of the algorithms proposed by this driver.
+ * Power management strategy: The device is suspended until a request
+ * is handled. For avoiding suspend/resume yoyo, the autosuspend is set to 2s.
*/
static int rk_crypto_pm_suspend(struct device *dev)
{
@@ -161,8 +182,17 @@ static struct rk_crypto_tmp *rk_cipher_algs[] = {
#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
static int rk_crypto_debugfs_show(struct seq_file *seq, void *v)
{
+ struct rk_crypto_info *dd;
unsigned int i;

+ spin_lock(&rocklist.lock);
+ list_for_each_entry(dd, &rocklist.dev_list, list) {
+ seq_printf(seq, "%s %s requests: %lu\n",
+ dev_driver_string(dd->dev), dev_name(dd->dev),
+ dd->nreq);
+ }
+ spin_unlock(&rocklist.lock);
+
for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
if (!rk_cipher_algs[i]->dev)
continue;
@@ -193,6 +223,18 @@ static int rk_crypto_debugfs_show(struct seq_file *seq, void *v)
DEFINE_SHOW_ATTRIBUTE(rk_crypto_debugfs);
#endif

+static void register_debugfs(struct rk_crypto_info *crypto_info)
+{
+#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
+ /* Ignore error of debugfs */
+ rocklist.dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL);
+ rocklist.dbgfs_stats = debugfs_create_file("stats", 0444,
+ rocklist.dbgfs_dir,
+ &rocklist,
+ &rk_crypto_debugfs_fops);
+#endif
+}
+
static int rk_crypto_register(struct rk_crypto_info *crypto_info)
{
unsigned int i, k;
@@ -250,6 +292,9 @@ static const struct of_device_id crypto_of_id_table[] = {
{ .compatible = "rockchip,rk3328-crypto",
.data = &rk3328_variant,
},
+ { .compatible = "rockchip,rk3399-crypto",
+ .data = &rk3399_variant,
+ },
{}
};
MODULE_DEVICE_TABLE(of, crypto_of_id_table);
@@ -257,7 +302,7 @@ MODULE_DEVICE_TABLE(of, crypto_of_id_table);
static int rk_crypto_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct rk_crypto_info *crypto_info;
+ struct rk_crypto_info *crypto_info, *first;
int err = 0;

crypto_info = devm_kzalloc(&pdev->dev,
@@ -316,22 +361,22 @@ static int rk_crypto_probe(struct platform_device *pdev)
if (err)
goto err_pm;

- err = rk_crypto_register(crypto_info);
- if (err) {
- dev_err(dev, "err in register alg");
- goto err_register_alg;
- }
+ spin_lock(&rocklist.lock);
+ first = list_first_entry_or_null(&rocklist.dev_list,
+ struct rk_crypto_info, list);
+ list_add_tail(&crypto_info->list, &rocklist.dev_list);
+ spin_unlock(&rocklist.lock);
+
+ if (!first) {
+ err = rk_crypto_register(crypto_info);
+ if (err) {
+ dev_err(dev, "Fail to register crypto algorithms");
+ goto err_register_alg;
+ }

-#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
- /* Ignore error of debugfs */
- crypto_info->dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL);
- crypto_info->dbgfs_stats = debugfs_create_file("stats", 0444,
- crypto_info->dbgfs_dir,
- crypto_info,
- &rk_crypto_debugfs_fops);
-#endif
+ register_debugfs(crypto_info);
+ }

- dev_info(dev, "Crypto Accelerator successfully registered\n");
return 0;

err_register_alg:
@@ -346,11 +391,20 @@ static int rk_crypto_probe(struct platform_device *pdev)
static int rk_crypto_remove(struct platform_device *pdev)
{
struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
+ struct rk_crypto_info *first;
+
+ spin_lock_bh(&rocklist.lock);
+ list_del(&crypto_tmp->list);
+ first = list_first_entry_or_null(&rocklist.dev_list,
+ struct rk_crypto_info, list);
+ spin_unlock_bh(&rocklist.lock);

+ if (!first) {
#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
- debugfs_remove_recursive(crypto_tmp->dbgfs_dir);
+ debugfs_remove_recursive(rocklist.dbgfs_dir);
#endif
- rk_crypto_unregister();
+ rk_crypto_unregister();
+ }
rk_crypto_pm_exit(crypto_tmp);
crypto_engine_exit(crypto_tmp->engine);
return 0;
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index ac979d67ced9..b2695258cade 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -190,6 +190,20 @@

#define RK_MAX_CLKS 4

+/*
+ * struct rockchip_ip - struct for managing a list of RK crypto instance
+ * @dev_list: Used for doing a list of rk_crypto_info
+ * @lock: Control access to dev_list
+ * @dbgfs_dir: Debugfs dentry for statistic directory
+ * @dbgfs_stats: Debugfs dentry for statistic counters
+ */
+struct rockchip_ip {
+ struct list_head dev_list;
+ spinlock_t lock; /* Control access to dev_list */
+ struct dentry *dbgfs_dir;
+ struct dentry *dbgfs_stats;
+};
+
struct rk_clks {
const char *name;
unsigned long max;
@@ -201,6 +215,7 @@ struct rk_variant {
};

struct rk_crypto_info {
+ struct list_head list;
struct device *dev;
struct clk_bulk_data *clks;
int num_clks;
@@ -208,19 +223,15 @@ struct rk_crypto_info {
void __iomem *reg;
int irq;
const struct rk_variant *variant;
+ unsigned long nreq;
struct crypto_engine *engine;
struct completion complete;
int status;
-#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
- struct dentry *dbgfs_dir;
- struct dentry *dbgfs_stats;
-#endif
};

/* the private variable of hash */
struct rk_ahash_ctx {
struct crypto_engine_ctx enginectx;
- struct rk_crypto_info *dev;
/* for fallback */
struct crypto_ahash *fallback_tfm;
};
@@ -236,7 +247,6 @@ struct rk_ahash_rctx {
/* the private variable of cipher */
struct rk_cipher_ctx {
struct crypto_engine_ctx enginectx;
- struct rk_crypto_info *dev;
unsigned int keylen;
u8 key[AES_MAX_KEY_SIZE];
u8 iv[AES_BLOCK_SIZE];
@@ -252,7 +262,7 @@ struct rk_cipher_rctx {

struct rk_crypto_tmp {
u32 type;
- struct rk_crypto_info *dev;
+ struct rk_crypto_info *dev;
union {
struct skcipher_alg skcipher;
struct ahash_alg hash;
@@ -276,4 +286,5 @@ extern struct rk_crypto_tmp rk_ahash_sha1;
extern struct rk_crypto_tmp rk_ahash_sha256;
extern struct rk_crypto_tmp rk_ahash_md5;

+struct rk_crypto_info *get_rk_crypto(void);
#endif
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 30f78256c955..a78ff3dcd0b1 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -199,8 +199,8 @@ static int rk_ahash_export(struct ahash_request *req, void *out)
static int rk_ahash_digest(struct ahash_request *req)
{
struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
- struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
- struct rk_crypto_info *dev = tctx->dev;
+ struct rk_crypto_info *dev;
+ struct crypto_engine *engine;

if (rk_ahash_need_fallback(req))
return rk_ahash_digest_fb(req);
@@ -208,9 +208,12 @@ static int rk_ahash_digest(struct ahash_request *req)
if (!req->nbytes)
return zero_message_process(req);

+ dev = get_rk_crypto();
+
rctx->dev = dev;
+ engine = dev->engine;

- return crypto_transfer_hash_request_to_engine(dev->engine, req);
+ return crypto_transfer_hash_request_to_engine(engine, req);
}

static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
@@ -260,9 +263,14 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
int i;
u32 v;

+ err = pm_runtime_resume_and_get(rkc->dev);
+ if (err)
+ return err;
+
rctx->mode = 0;

algt->stat_req++;
+ rkc->nreq++;

switch (crypto_ahash_digestsize(tfm)) {
case SHA1_DIGEST_SIZE:
@@ -313,6 +321,8 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
}

theend:
+ pm_runtime_put_autosuspend(rkc->dev);
+
local_bh_disable();
crypto_finalize_hash_request(engine, breq, err);
local_bh_enable();
@@ -323,21 +333,15 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
static int rk_cra_hash_init(struct crypto_tfm *tfm)
{
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
- struct rk_crypto_tmp *algt;
- struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
-
const char *alg_name = crypto_tfm_alg_name(tfm);
- int err;
-
- algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
-
- tctx->dev = algt->dev;
+ struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);

/* for fallback */
tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(tctx->fallback_tfm)) {
- dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
+ dev_err(algt->dev->dev, "Could not load fallback driver.\n");
return PTR_ERR(tctx->fallback_tfm);
}

@@ -349,15 +353,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
tctx->enginectx.op.prepare_request = rk_hash_prepare;
tctx->enginectx.op.unprepare_request = rk_hash_unprepare;

- err = pm_runtime_resume_and_get(tctx->dev->dev);
- if (err < 0)
- goto error_pm;
-
return 0;
-error_pm:
- crypto_free_ahash(tctx->fallback_tfm);
-
- return err;
}

static void rk_cra_hash_exit(struct crypto_tfm *tfm)
@@ -365,7 +361,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);

crypto_free_ahash(tctx->fallback_tfm);
- pm_runtime_put_autosuspend(tctx->dev->dev);
}

struct rk_crypto_tmp rk_ahash_sha1 = {
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 0b1c90ababb7..59069457582b 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -17,11 +17,11 @@
static int rk_cipher_need_fallback(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- unsigned int bs = crypto_skcipher_blocksize(tfm);
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
struct scatterlist *sgs, *sgd;
unsigned int stodo, dtodo, len;
+ unsigned int bs = crypto_skcipher_blocksize(tfm);

if (!req->cryptlen)
return true;
@@ -84,15 +84,16 @@ static int rk_cipher_fallback(struct skcipher_request *areq)

static int rk_cipher_handle_req(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *rkc = tctx->dev;
- struct crypto_engine *engine = rkc->engine;
+ struct rk_crypto_info *rkc;
+ struct crypto_engine *engine;

if (rk_cipher_need_fallback(req))
return rk_cipher_fallback(req);

+ rkc = get_rk_crypto();
+
+ engine = rkc->engine;
rctx->dev = rkc;

return crypto_transfer_skcipher_request_to_engine(engine, req);
@@ -307,7 +308,12 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
struct rk_crypto_info *rkc = rctx->dev;

+ err = pm_runtime_resume_and_get(rkc->dev);
+ if (err)
+ return err;
+
algt->stat_req++;
+ rkc->nreq++;

ivsize = crypto_skcipher_ivsize(tfm);
if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
@@ -401,6 +407,8 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
}

theend:
+ pm_runtime_put_autosuspend(rkc->dev);
+
local_bh_disable();
crypto_finalize_skcipher_request(engine, areq, err);
local_bh_enable();
@@ -420,18 +428,13 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
static int rk_cipher_tfm_init(struct crypto_skcipher *tfm)
{
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
const char *name = crypto_tfm_alg_name(&tfm->base);
- struct rk_crypto_tmp *algt;
- int err;
-
- algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
-
- ctx->dev = algt->dev;
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);

ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(ctx->fallback_tfm)) {
- dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
+ dev_err(algt->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
name, PTR_ERR(ctx->fallback_tfm));
return PTR_ERR(ctx->fallback_tfm);
}
@@ -441,14 +444,7 @@ static int rk_cipher_tfm_init(struct crypto_skcipher *tfm)

ctx->enginectx.op.do_one_request = rk_cipher_run;

- err = pm_runtime_resume_and_get(ctx->dev->dev);
- if (err < 0)
- goto error_pm;
-
return 0;
-error_pm:
- crypto_free_skcipher(ctx->fallback_tfm);
- return err;
}

static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm)
@@ -457,7 +453,6 @@ static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm)

memzero_explicit(ctx->key, ctx->keylen);
crypto_free_skcipher(ctx->fallback_tfm);
- pm_runtime_put_autosuspend(ctx->dev->dev);
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
--
2.35.1

2022-04-26 08:39:34

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v6 24/33] dt-bindings: crypto: convert rockchip-crypto to YAML

Convert rockchip-crypto to YAML.

Signed-off-by: Corentin Labbe <[email protected]>
---
.../crypto/rockchip,rk3288-crypto.yaml | 64 +++++++++++++++++++
.../bindings/crypto/rockchip-crypto.txt | 28 --------
2 files changed, 64 insertions(+), 28 deletions(-)
create mode 100644 Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
delete mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt

diff --git a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
new file mode 100644
index 000000000000..8a219d439d02
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/rockchip,rk3288-crypto.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip Electronics Security Accelerator
+
+maintainers:
+ - Heiko Stuebner <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - rockchip,rk3288-crypto
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 4
+
+ clock-names:
+ items:
+ - const: aclk
+ - const: hclk
+ - const: sclk
+ - const: apb_pclk
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ items:
+ - const: crypto-rst
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/rk3288-cru.h>
+ crypto@ff8a0000 {
+ compatible = "rockchip,rk3288-crypto";
+ reg = <0xff8a0000 0x4000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>,
+ <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>;
+ clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+ resets = <&cru SRST_CRYPTO>;
+ reset-names = "crypto-rst";
+ };
diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt
deleted file mode 100644
index 5e2ba385b8c9..000000000000
--- a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Rockchip Electronics And Security Accelerator
-
-Required properties:
-- compatible: Should be "rockchip,rk3288-crypto"
-- reg: Base physical address of the engine and length of memory mapped
- region
-- interrupts: Interrupt number
-- clocks: Reference to the clocks about crypto
-- clock-names: "aclk" used to clock data
- "hclk" used to clock data
- "sclk" used to clock crypto accelerator
- "apb_pclk" used to clock dma
-- resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
-- reset-names: Must include the name "crypto-rst".
-
-Examples:
-
- crypto: cypto-controller@ff8a0000 {
- compatible = "rockchip,rk3288-crypto";
- reg = <0xff8a0000 0x4000>;
- interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>,
- <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>;
- clock-names = "aclk", "hclk", "sclk", "apb_pclk";
- resets = <&cru SRST_CRYPTO>;
- reset-names = "crypto-rst";
- };
--
2.35.1

2022-04-26 08:49:17

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v6 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

On 25/04/2022 22:21, Corentin Labbe wrote:
> The latest addition to the rockchip crypto driver need to update the
> driver bindings.
>
> Signed-off-by: Corentin Labbe <[email protected]>
> ---
> .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
> 1 file changed, 77 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
> index 8a219d439d02..ad604d7e4bc0 100644
> --- a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
> +++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
> @@ -13,6 +13,8 @@ properties:
> compatible:
> enum:
> - rockchip,rk3288-crypto
> + - rockchip,rk3328-crypto
> + - rockchip,rk3399-crypto
>
> reg:
> maxItems: 1
> @@ -21,21 +23,88 @@ properties:
> maxItems: 1
>
> clocks:
> + minItems: 3
> maxItems: 4
>
> clock-names:
> - items:
> - - const: aclk
> - - const: hclk
> - - const: sclk
> - - const: apb_pclk
> + minItems: 3
> + maxItems: 4
>
> resets:
> - maxItems: 1
> + minItems: 1
> + maxItems: 3
>
> reset-names:
> - items:
> - - const: crypto-rst
> + minItems: 1
> + maxItems: 3
> +
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: rockchip,rk3288-crypto
> + then:
> + properties:
> + clocks:
> + minItems: 4
> + clock-names:
> + items:
> + - const: "aclk"

No quotes (here and other places).

Rest looks good.

Best regards,
Krzysztof