1 // SPDX-License-Identifier: GPL-2.0
3 * sun8i-ce-core.c - hardware cryptographic offloader for
4 * Allwinner H3/A64/H5/H2+/H6/R40 SoC
6 * Copyright (C) 2015-2019 Corentin Labbe <clabbe.montjoie@gmail.com>
8 * Core file which registers crypto algorithms supported by the CryptoEngine.
10 * You could find a link for the datasheet in Documentation/arm/sunxi.rst
12 #include <linux/clk.h>
13 #include <linux/crypto.h>
14 #include <linux/delay.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/interrupt.h>
18 #include <linux/irq.h>
19 #include <linux/module.h>
21 #include <linux/of_device.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/reset.h>
25 #include <crypto/internal/rng.h>
26 #include <crypto/internal/skcipher.h>
31 * mod clock is lower on H3 than other SoC due to some DMA timeout occurring
33 * If you want to tune mod clock, loading driver and passing selftest is
34 * insufficient, you need to test with some LUKS test (mount and write to it)
36 static const struct ce_variant ce_h3_variant
= {
37 .alg_cipher
= { CE_ALG_AES
, CE_ALG_DES
, CE_ALG_3DES
,
39 .alg_hash
= { CE_ALG_MD5
, CE_ALG_SHA1
, CE_ALG_SHA224
, CE_ALG_SHA256
,
40 CE_ALG_SHA384
, CE_ALG_SHA512
42 .op_mode
= { CE_OP_ECB
, CE_OP_CBC
45 { "bus", 0, 200000000 },
46 { "mod", 50000000, 0 },
50 .trng
= CE_ID_NOTSUPP
,
53 static const struct ce_variant ce_h5_variant
= {
54 .alg_cipher
= { CE_ALG_AES
, CE_ALG_DES
, CE_ALG_3DES
,
56 .alg_hash
= { CE_ALG_MD5
, CE_ALG_SHA1
, CE_ALG_SHA224
, CE_ALG_SHA256
,
57 CE_ID_NOTSUPP
, CE_ID_NOTSUPP
59 .op_mode
= { CE_OP_ECB
, CE_OP_CBC
62 { "bus", 0, 200000000 },
63 { "mod", 300000000, 0 },
67 .trng
= CE_ID_NOTSUPP
,
70 static const struct ce_variant ce_h6_variant
= {
71 .alg_cipher
= { CE_ALG_AES
, CE_ALG_DES
, CE_ALG_3DES
,
73 .alg_hash
= { CE_ALG_MD5
, CE_ALG_SHA1
, CE_ALG_SHA224
, CE_ALG_SHA256
,
74 CE_ALG_SHA384
, CE_ALG_SHA512
76 .op_mode
= { CE_OP_ECB
, CE_OP_CBC
78 .cipher_t_dlen_in_bytes
= true,
79 .hash_t_dlen_in_bits
= true,
80 .prng_t_dlen_in_bytes
= true,
81 .trng_t_dlen_in_bytes
= true,
83 { "bus", 0, 200000000 },
84 { "mod", 300000000, 0 },
85 { "ram", 0, 400000000 },
88 .prng
= CE_ALG_PRNG_V2
,
89 .trng
= CE_ALG_TRNG_V2
,
92 static const struct ce_variant ce_a64_variant
= {
93 .alg_cipher
= { CE_ALG_AES
, CE_ALG_DES
, CE_ALG_3DES
,
95 .alg_hash
= { CE_ALG_MD5
, CE_ALG_SHA1
, CE_ALG_SHA224
, CE_ALG_SHA256
,
96 CE_ID_NOTSUPP
, CE_ID_NOTSUPP
98 .op_mode
= { CE_OP_ECB
, CE_OP_CBC
101 { "bus", 0, 200000000 },
102 { "mod", 300000000, 0 },
106 .trng
= CE_ID_NOTSUPP
,
109 static const struct ce_variant ce_r40_variant
= {
110 .alg_cipher
= { CE_ALG_AES
, CE_ALG_DES
, CE_ALG_3DES
,
112 .alg_hash
= { CE_ALG_MD5
, CE_ALG_SHA1
, CE_ALG_SHA224
, CE_ALG_SHA256
,
113 CE_ID_NOTSUPP
, CE_ID_NOTSUPP
115 .op_mode
= { CE_OP_ECB
, CE_OP_CBC
118 { "bus", 0, 200000000 },
119 { "mod", 300000000, 0 },
123 .trng
= CE_ID_NOTSUPP
,
127 * sun8i_ce_get_engine_number() get the next channel slot
128 * This is a simple round-robin way of getting the next channel
129 * The flow 3 is reserve for xRNG operations
131 int sun8i_ce_get_engine_number(struct sun8i_ce_dev
*ce
)
133 return atomic_inc_return(&ce
->flow
) % (MAXFLOW
- 1);
136 int sun8i_ce_run_task(struct sun8i_ce_dev
*ce
, int flow
, const char *name
)
140 struct ce_task
*cet
= ce
->chanlist
[flow
].tl
;
142 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
143 ce
->chanlist
[flow
].stat_req
++;
146 mutex_lock(&ce
->mlock
);
148 v
= readl(ce
->base
+ CE_ICR
);
150 writel(v
, ce
->base
+ CE_ICR
);
152 reinit_completion(&ce
->chanlist
[flow
].complete
);
153 writel(ce
->chanlist
[flow
].t_phy
, ce
->base
+ CE_TDQ
);
155 ce
->chanlist
[flow
].status
= 0;
156 /* Be sure all data is written before enabling the task */
159 /* Only H6 needs to write a part of t_common_ctl along with "1", but since it is ignored
160 * on older SoCs, we have no reason to complicate things.
162 v
= 1 | ((le32_to_cpu(ce
->chanlist
[flow
].tl
->t_common_ctl
) & 0x7F) << 8);
163 writel(v
, ce
->base
+ CE_TLR
);
164 mutex_unlock(&ce
->mlock
);
166 wait_for_completion_interruptible_timeout(&ce
->chanlist
[flow
].complete
,
167 msecs_to_jiffies(ce
->chanlist
[flow
].timeout
));
169 if (ce
->chanlist
[flow
].status
== 0) {
170 dev_err(ce
->dev
, "DMA timeout for %s (tm=%d) on flow %d\n", name
,
171 ce
->chanlist
[flow
].timeout
, flow
);
174 /* No need to lock for this read, the channel is locked so
175 * nothing could modify the error value for this channel
177 v
= readl(ce
->base
+ CE_ESR
);
178 switch (ce
->variant
->esr
) {
180 /* Sadly, the error bit is not per flow */
182 dev_err(ce
->dev
, "CE ERROR: %x for flow %x\n", v
, flow
);
184 print_hex_dump(KERN_INFO
, "TASK: ", DUMP_PREFIX_NONE
, 16, 4,
185 cet
, sizeof(struct ce_task
), false);
187 if (v
& CE_ERR_ALGO_NOTSUP
)
188 dev_err(ce
->dev
, "CE ERROR: algorithm not supported\n");
189 if (v
& CE_ERR_DATALEN
)
190 dev_err(ce
->dev
, "CE ERROR: data length error\n");
191 if (v
& CE_ERR_KEYSRAM
)
192 dev_err(ce
->dev
, "CE ERROR: keysram access error for AES\n");
200 dev_err(ce
->dev
, "CE ERROR: %x for flow %x\n", v
, flow
);
202 print_hex_dump(KERN_INFO
, "TASK: ", DUMP_PREFIX_NONE
, 16, 4,
203 cet
, sizeof(struct ce_task
), false);
205 if (v
& CE_ERR_ALGO_NOTSUP
)
206 dev_err(ce
->dev
, "CE ERROR: algorithm not supported\n");
207 if (v
& CE_ERR_DATALEN
)
208 dev_err(ce
->dev
, "CE ERROR: data length error\n");
209 if (v
& CE_ERR_KEYSRAM
)
210 dev_err(ce
->dev
, "CE ERROR: keysram access error for AES\n");
216 dev_err(ce
->dev
, "CE ERROR: %x for flow %x\n", v
, flow
);
218 print_hex_dump(KERN_INFO
, "TASK: ", DUMP_PREFIX_NONE
, 16, 4,
219 cet
, sizeof(struct ce_task
), false);
221 if (v
& CE_ERR_ALGO_NOTSUP
)
222 dev_err(ce
->dev
, "CE ERROR: algorithm not supported\n");
223 if (v
& CE_ERR_DATALEN
)
224 dev_err(ce
->dev
, "CE ERROR: data length error\n");
225 if (v
& CE_ERR_KEYSRAM
)
226 dev_err(ce
->dev
, "CE ERROR: keysram access error for AES\n");
227 if (v
& CE_ERR_ADDR_INVALID
)
228 dev_err(ce
->dev
, "CE ERROR: address invalid\n");
229 if (v
& CE_ERR_KEYLADDER
)
230 dev_err(ce
->dev
, "CE ERROR: key ladder configuration error\n");
237 static irqreturn_t
ce_irq_handler(int irq
, void *data
)
239 struct sun8i_ce_dev
*ce
= (struct sun8i_ce_dev
*)data
;
243 p
= readl(ce
->base
+ CE_ISR
);
244 for (flow
= 0; flow
< MAXFLOW
; flow
++) {
245 if (p
& (BIT(flow
))) {
246 writel(BIT(flow
), ce
->base
+ CE_ISR
);
247 ce
->chanlist
[flow
].status
= 1;
248 complete(&ce
->chanlist
[flow
].complete
);
255 static struct sun8i_ce_alg_template ce_algs
[] = {
257 .type
= CRYPTO_ALG_TYPE_SKCIPHER
,
258 .ce_algo_id
= CE_ID_CIPHER_AES
,
259 .ce_blockmode
= CE_ID_OP_CBC
,
262 .cra_name
= "cbc(aes)",
263 .cra_driver_name
= "cbc-aes-sun8i-ce",
265 .cra_blocksize
= AES_BLOCK_SIZE
,
266 .cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
|
267 CRYPTO_ALG_ASYNC
| CRYPTO_ALG_ALLOCATES_MEMORY
|
268 CRYPTO_ALG_NEED_FALLBACK
,
269 .cra_ctxsize
= sizeof(struct sun8i_cipher_tfm_ctx
),
270 .cra_module
= THIS_MODULE
,
271 .cra_alignmask
= 0xf,
272 .cra_init
= sun8i_ce_cipher_init
,
273 .cra_exit
= sun8i_ce_cipher_exit
,
275 .min_keysize
= AES_MIN_KEY_SIZE
,
276 .max_keysize
= AES_MAX_KEY_SIZE
,
277 .ivsize
= AES_BLOCK_SIZE
,
278 .setkey
= sun8i_ce_aes_setkey
,
279 .encrypt
= sun8i_ce_skencrypt
,
280 .decrypt
= sun8i_ce_skdecrypt
,
284 .type
= CRYPTO_ALG_TYPE_SKCIPHER
,
285 .ce_algo_id
= CE_ID_CIPHER_AES
,
286 .ce_blockmode
= CE_ID_OP_ECB
,
289 .cra_name
= "ecb(aes)",
290 .cra_driver_name
= "ecb-aes-sun8i-ce",
292 .cra_blocksize
= AES_BLOCK_SIZE
,
293 .cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
|
294 CRYPTO_ALG_ASYNC
| CRYPTO_ALG_ALLOCATES_MEMORY
|
295 CRYPTO_ALG_NEED_FALLBACK
,
296 .cra_ctxsize
= sizeof(struct sun8i_cipher_tfm_ctx
),
297 .cra_module
= THIS_MODULE
,
298 .cra_alignmask
= 0xf,
299 .cra_init
= sun8i_ce_cipher_init
,
300 .cra_exit
= sun8i_ce_cipher_exit
,
302 .min_keysize
= AES_MIN_KEY_SIZE
,
303 .max_keysize
= AES_MAX_KEY_SIZE
,
304 .setkey
= sun8i_ce_aes_setkey
,
305 .encrypt
= sun8i_ce_skencrypt
,
306 .decrypt
= sun8i_ce_skdecrypt
,
310 .type
= CRYPTO_ALG_TYPE_SKCIPHER
,
311 .ce_algo_id
= CE_ID_CIPHER_DES3
,
312 .ce_blockmode
= CE_ID_OP_CBC
,
315 .cra_name
= "cbc(des3_ede)",
316 .cra_driver_name
= "cbc-des3-sun8i-ce",
318 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
319 .cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
|
320 CRYPTO_ALG_ASYNC
| CRYPTO_ALG_ALLOCATES_MEMORY
|
321 CRYPTO_ALG_NEED_FALLBACK
,
322 .cra_ctxsize
= sizeof(struct sun8i_cipher_tfm_ctx
),
323 .cra_module
= THIS_MODULE
,
324 .cra_alignmask
= 0xf,
325 .cra_init
= sun8i_ce_cipher_init
,
326 .cra_exit
= sun8i_ce_cipher_exit
,
328 .min_keysize
= DES3_EDE_KEY_SIZE
,
329 .max_keysize
= DES3_EDE_KEY_SIZE
,
330 .ivsize
= DES3_EDE_BLOCK_SIZE
,
331 .setkey
= sun8i_ce_des3_setkey
,
332 .encrypt
= sun8i_ce_skencrypt
,
333 .decrypt
= sun8i_ce_skdecrypt
,
337 .type
= CRYPTO_ALG_TYPE_SKCIPHER
,
338 .ce_algo_id
= CE_ID_CIPHER_DES3
,
339 .ce_blockmode
= CE_ID_OP_ECB
,
342 .cra_name
= "ecb(des3_ede)",
343 .cra_driver_name
= "ecb-des3-sun8i-ce",
345 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
346 .cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
|
347 CRYPTO_ALG_ASYNC
| CRYPTO_ALG_ALLOCATES_MEMORY
|
348 CRYPTO_ALG_NEED_FALLBACK
,
349 .cra_ctxsize
= sizeof(struct sun8i_cipher_tfm_ctx
),
350 .cra_module
= THIS_MODULE
,
351 .cra_alignmask
= 0xf,
352 .cra_init
= sun8i_ce_cipher_init
,
353 .cra_exit
= sun8i_ce_cipher_exit
,
355 .min_keysize
= DES3_EDE_KEY_SIZE
,
356 .max_keysize
= DES3_EDE_KEY_SIZE
,
357 .setkey
= sun8i_ce_des3_setkey
,
358 .encrypt
= sun8i_ce_skencrypt
,
359 .decrypt
= sun8i_ce_skdecrypt
,
362 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_HASH
363 { .type
= CRYPTO_ALG_TYPE_AHASH
,
364 .ce_algo_id
= CE_ID_HASH_MD5
,
366 .init
= sun8i_ce_hash_init
,
367 .update
= sun8i_ce_hash_update
,
368 .final
= sun8i_ce_hash_final
,
369 .finup
= sun8i_ce_hash_finup
,
370 .digest
= sun8i_ce_hash_digest
,
371 .export
= sun8i_ce_hash_export
,
372 .import
= sun8i_ce_hash_import
,
374 .digestsize
= MD5_DIGEST_SIZE
,
375 .statesize
= sizeof(struct md5_state
),
378 .cra_driver_name
= "md5-sun8i-ce",
381 .cra_flags
= CRYPTO_ALG_TYPE_AHASH
|
383 CRYPTO_ALG_NEED_FALLBACK
,
384 .cra_blocksize
= MD5_HMAC_BLOCK_SIZE
,
385 .cra_ctxsize
= sizeof(struct sun8i_ce_hash_tfm_ctx
),
386 .cra_module
= THIS_MODULE
,
387 .cra_init
= sun8i_ce_hash_crainit
,
388 .cra_exit
= sun8i_ce_hash_craexit
,
393 { .type
= CRYPTO_ALG_TYPE_AHASH
,
394 .ce_algo_id
= CE_ID_HASH_SHA1
,
396 .init
= sun8i_ce_hash_init
,
397 .update
= sun8i_ce_hash_update
,
398 .final
= sun8i_ce_hash_final
,
399 .finup
= sun8i_ce_hash_finup
,
400 .digest
= sun8i_ce_hash_digest
,
401 .export
= sun8i_ce_hash_export
,
402 .import
= sun8i_ce_hash_import
,
404 .digestsize
= SHA1_DIGEST_SIZE
,
405 .statesize
= sizeof(struct sha1_state
),
408 .cra_driver_name
= "sha1-sun8i-ce",
411 .cra_flags
= CRYPTO_ALG_TYPE_AHASH
|
413 CRYPTO_ALG_NEED_FALLBACK
,
414 .cra_blocksize
= SHA1_BLOCK_SIZE
,
415 .cra_ctxsize
= sizeof(struct sun8i_ce_hash_tfm_ctx
),
416 .cra_module
= THIS_MODULE
,
417 .cra_init
= sun8i_ce_hash_crainit
,
418 .cra_exit
= sun8i_ce_hash_craexit
,
423 { .type
= CRYPTO_ALG_TYPE_AHASH
,
424 .ce_algo_id
= CE_ID_HASH_SHA224
,
426 .init
= sun8i_ce_hash_init
,
427 .update
= sun8i_ce_hash_update
,
428 .final
= sun8i_ce_hash_final
,
429 .finup
= sun8i_ce_hash_finup
,
430 .digest
= sun8i_ce_hash_digest
,
431 .export
= sun8i_ce_hash_export
,
432 .import
= sun8i_ce_hash_import
,
434 .digestsize
= SHA224_DIGEST_SIZE
,
435 .statesize
= sizeof(struct sha256_state
),
437 .cra_name
= "sha224",
438 .cra_driver_name
= "sha224-sun8i-ce",
441 .cra_flags
= CRYPTO_ALG_TYPE_AHASH
|
443 CRYPTO_ALG_NEED_FALLBACK
,
444 .cra_blocksize
= SHA224_BLOCK_SIZE
,
445 .cra_ctxsize
= sizeof(struct sun8i_ce_hash_tfm_ctx
),
446 .cra_module
= THIS_MODULE
,
447 .cra_init
= sun8i_ce_hash_crainit
,
448 .cra_exit
= sun8i_ce_hash_craexit
,
453 { .type
= CRYPTO_ALG_TYPE_AHASH
,
454 .ce_algo_id
= CE_ID_HASH_SHA256
,
456 .init
= sun8i_ce_hash_init
,
457 .update
= sun8i_ce_hash_update
,
458 .final
= sun8i_ce_hash_final
,
459 .finup
= sun8i_ce_hash_finup
,
460 .digest
= sun8i_ce_hash_digest
,
461 .export
= sun8i_ce_hash_export
,
462 .import
= sun8i_ce_hash_import
,
464 .digestsize
= SHA256_DIGEST_SIZE
,
465 .statesize
= sizeof(struct sha256_state
),
467 .cra_name
= "sha256",
468 .cra_driver_name
= "sha256-sun8i-ce",
471 .cra_flags
= CRYPTO_ALG_TYPE_AHASH
|
473 CRYPTO_ALG_NEED_FALLBACK
,
474 .cra_blocksize
= SHA256_BLOCK_SIZE
,
475 .cra_ctxsize
= sizeof(struct sun8i_ce_hash_tfm_ctx
),
476 .cra_module
= THIS_MODULE
,
477 .cra_init
= sun8i_ce_hash_crainit
,
478 .cra_exit
= sun8i_ce_hash_craexit
,
483 { .type
= CRYPTO_ALG_TYPE_AHASH
,
484 .ce_algo_id
= CE_ID_HASH_SHA384
,
486 .init
= sun8i_ce_hash_init
,
487 .update
= sun8i_ce_hash_update
,
488 .final
= sun8i_ce_hash_final
,
489 .finup
= sun8i_ce_hash_finup
,
490 .digest
= sun8i_ce_hash_digest
,
491 .export
= sun8i_ce_hash_export
,
492 .import
= sun8i_ce_hash_import
,
494 .digestsize
= SHA384_DIGEST_SIZE
,
495 .statesize
= sizeof(struct sha512_state
),
497 .cra_name
= "sha384",
498 .cra_driver_name
= "sha384-sun8i-ce",
501 .cra_flags
= CRYPTO_ALG_TYPE_AHASH
|
503 CRYPTO_ALG_NEED_FALLBACK
,
504 .cra_blocksize
= SHA384_BLOCK_SIZE
,
505 .cra_ctxsize
= sizeof(struct sun8i_ce_hash_tfm_ctx
),
506 .cra_module
= THIS_MODULE
,
507 .cra_init
= sun8i_ce_hash_crainit
,
508 .cra_exit
= sun8i_ce_hash_craexit
,
513 { .type
= CRYPTO_ALG_TYPE_AHASH
,
514 .ce_algo_id
= CE_ID_HASH_SHA512
,
516 .init
= sun8i_ce_hash_init
,
517 .update
= sun8i_ce_hash_update
,
518 .final
= sun8i_ce_hash_final
,
519 .finup
= sun8i_ce_hash_finup
,
520 .digest
= sun8i_ce_hash_digest
,
521 .export
= sun8i_ce_hash_export
,
522 .import
= sun8i_ce_hash_import
,
524 .digestsize
= SHA512_DIGEST_SIZE
,
525 .statesize
= sizeof(struct sha512_state
),
527 .cra_name
= "sha512",
528 .cra_driver_name
= "sha512-sun8i-ce",
531 .cra_flags
= CRYPTO_ALG_TYPE_AHASH
|
533 CRYPTO_ALG_NEED_FALLBACK
,
534 .cra_blocksize
= SHA512_BLOCK_SIZE
,
535 .cra_ctxsize
= sizeof(struct sun8i_ce_hash_tfm_ctx
),
536 .cra_module
= THIS_MODULE
,
537 .cra_init
= sun8i_ce_hash_crainit
,
538 .cra_exit
= sun8i_ce_hash_craexit
,
544 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
546 .type
= CRYPTO_ALG_TYPE_RNG
,
549 .cra_name
= "stdrng",
550 .cra_driver_name
= "sun8i-ce-prng",
552 .cra_ctxsize
= sizeof(struct sun8i_ce_rng_tfm_ctx
),
553 .cra_module
= THIS_MODULE
,
554 .cra_init
= sun8i_ce_prng_init
,
555 .cra_exit
= sun8i_ce_prng_exit
,
557 .generate
= sun8i_ce_prng_generate
,
558 .seed
= sun8i_ce_prng_seed
,
559 .seedsize
= PRNG_SEED_SIZE
,
565 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
566 static int sun8i_ce_debugfs_show(struct seq_file
*seq
, void *v
)
568 struct sun8i_ce_dev
*ce
= seq
->private;
571 for (i
= 0; i
< MAXFLOW
; i
++)
572 seq_printf(seq
, "Channel %d: nreq %lu\n", i
, ce
->chanlist
[i
].stat_req
);
574 for (i
= 0; i
< ARRAY_SIZE(ce_algs
); i
++) {
577 switch (ce_algs
[i
].type
) {
578 case CRYPTO_ALG_TYPE_SKCIPHER
:
579 seq_printf(seq
, "%s %s %lu %lu\n",
580 ce_algs
[i
].alg
.skcipher
.base
.cra_driver_name
,
581 ce_algs
[i
].alg
.skcipher
.base
.cra_name
,
582 ce_algs
[i
].stat_req
, ce_algs
[i
].stat_fb
);
584 case CRYPTO_ALG_TYPE_AHASH
:
585 seq_printf(seq
, "%s %s %lu %lu\n",
586 ce_algs
[i
].alg
.hash
.halg
.base
.cra_driver_name
,
587 ce_algs
[i
].alg
.hash
.halg
.base
.cra_name
,
588 ce_algs
[i
].stat_req
, ce_algs
[i
].stat_fb
);
590 case CRYPTO_ALG_TYPE_RNG
:
591 seq_printf(seq
, "%s %s %lu %lu\n",
592 ce_algs
[i
].alg
.rng
.base
.cra_driver_name
,
593 ce_algs
[i
].alg
.rng
.base
.cra_name
,
594 ce_algs
[i
].stat_req
, ce_algs
[i
].stat_bytes
);
598 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
599 seq_printf(seq
, "HWRNG %lu %lu\n",
600 ce
->hwrng_stat_req
, ce
->hwrng_stat_bytes
);
605 DEFINE_SHOW_ATTRIBUTE(sun8i_ce_debugfs
);
608 static void sun8i_ce_free_chanlist(struct sun8i_ce_dev
*ce
, int i
)
611 crypto_engine_exit(ce
->chanlist
[i
].engine
);
612 if (ce
->chanlist
[i
].tl
)
613 dma_free_coherent(ce
->dev
, sizeof(struct ce_task
),
615 ce
->chanlist
[i
].t_phy
);
621 * Allocate the channel list structure
623 static int sun8i_ce_allocate_chanlist(struct sun8i_ce_dev
*ce
)
627 ce
->chanlist
= devm_kcalloc(ce
->dev
, MAXFLOW
,
628 sizeof(struct sun8i_ce_flow
), GFP_KERNEL
);
632 for (i
= 0; i
< MAXFLOW
; i
++) {
633 init_completion(&ce
->chanlist
[i
].complete
);
635 ce
->chanlist
[i
].engine
= crypto_engine_alloc_init(ce
->dev
, true);
636 if (!ce
->chanlist
[i
].engine
) {
637 dev_err(ce
->dev
, "Cannot allocate engine\n");
642 err
= crypto_engine_start(ce
->chanlist
[i
].engine
);
644 dev_err(ce
->dev
, "Cannot start engine\n");
647 ce
->chanlist
[i
].tl
= dma_alloc_coherent(ce
->dev
,
648 sizeof(struct ce_task
),
649 &ce
->chanlist
[i
].t_phy
,
651 if (!ce
->chanlist
[i
].tl
) {
652 dev_err(ce
->dev
, "Cannot get DMA memory for task %d\n",
660 sun8i_ce_free_chanlist(ce
, i
);
665 * Power management strategy: The device is suspended unless a TFM exists for
666 * one of the algorithms proposed by this driver.
668 static int sun8i_ce_pm_suspend(struct device
*dev
)
670 struct sun8i_ce_dev
*ce
= dev_get_drvdata(dev
);
673 reset_control_assert(ce
->reset
);
674 for (i
= 0; i
< CE_MAX_CLOCKS
; i
++)
675 clk_disable_unprepare(ce
->ceclks
[i
]);
679 static int sun8i_ce_pm_resume(struct device
*dev
)
681 struct sun8i_ce_dev
*ce
= dev_get_drvdata(dev
);
684 for (i
= 0; i
< CE_MAX_CLOCKS
; i
++) {
685 if (!ce
->variant
->ce_clks
[i
].name
)
687 err
= clk_prepare_enable(ce
->ceclks
[i
]);
689 dev_err(ce
->dev
, "Cannot prepare_enable %s\n",
690 ce
->variant
->ce_clks
[i
].name
);
694 err
= reset_control_deassert(ce
->reset
);
696 dev_err(ce
->dev
, "Cannot deassert reset control\n");
701 sun8i_ce_pm_suspend(dev
);
705 static const struct dev_pm_ops sun8i_ce_pm_ops
= {
706 SET_RUNTIME_PM_OPS(sun8i_ce_pm_suspend
, sun8i_ce_pm_resume
, NULL
)
709 static int sun8i_ce_pm_init(struct sun8i_ce_dev
*ce
)
713 pm_runtime_use_autosuspend(ce
->dev
);
714 pm_runtime_set_autosuspend_delay(ce
->dev
, 2000);
716 err
= pm_runtime_set_suspended(ce
->dev
);
719 pm_runtime_enable(ce
->dev
);
723 static void sun8i_ce_pm_exit(struct sun8i_ce_dev
*ce
)
725 pm_runtime_disable(ce
->dev
);
728 static int sun8i_ce_get_clks(struct sun8i_ce_dev
*ce
)
733 for (i
= 0; i
< CE_MAX_CLOCKS
; i
++) {
734 if (!ce
->variant
->ce_clks
[i
].name
)
736 ce
->ceclks
[i
] = devm_clk_get(ce
->dev
, ce
->variant
->ce_clks
[i
].name
);
737 if (IS_ERR(ce
->ceclks
[i
])) {
738 err
= PTR_ERR(ce
->ceclks
[i
]);
739 dev_err(ce
->dev
, "Cannot get %s CE clock err=%d\n",
740 ce
->variant
->ce_clks
[i
].name
, err
);
743 cr
= clk_get_rate(ce
->ceclks
[i
]);
746 if (ce
->variant
->ce_clks
[i
].freq
> 0 &&
747 cr
!= ce
->variant
->ce_clks
[i
].freq
) {
748 dev_info(ce
->dev
, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n",
749 ce
->variant
->ce_clks
[i
].name
,
750 ce
->variant
->ce_clks
[i
].freq
,
751 ce
->variant
->ce_clks
[i
].freq
/ 1000000,
753 err
= clk_set_rate(ce
->ceclks
[i
], ce
->variant
->ce_clks
[i
].freq
);
755 dev_err(ce
->dev
, "Fail to set %s clk speed to %lu hz\n",
756 ce
->variant
->ce_clks
[i
].name
,
757 ce
->variant
->ce_clks
[i
].freq
);
759 if (ce
->variant
->ce_clks
[i
].max_freq
> 0 &&
760 cr
> ce
->variant
->ce_clks
[i
].max_freq
)
761 dev_warn(ce
->dev
, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)",
762 ce
->variant
->ce_clks
[i
].name
, cr
,
763 ce
->variant
->ce_clks
[i
].max_freq
);
768 static int sun8i_ce_register_algs(struct sun8i_ce_dev
*ce
)
770 int ce_method
, err
, id
;
773 for (i
= 0; i
< ARRAY_SIZE(ce_algs
); i
++) {
775 switch (ce_algs
[i
].type
) {
776 case CRYPTO_ALG_TYPE_SKCIPHER
:
777 id
= ce_algs
[i
].ce_algo_id
;
778 ce_method
= ce
->variant
->alg_cipher
[id
];
779 if (ce_method
== CE_ID_NOTSUPP
) {
781 "DEBUG: Algo of %s not supported\n",
782 ce_algs
[i
].alg
.skcipher
.base
.cra_name
);
783 ce_algs
[i
].ce
= NULL
;
786 id
= ce_algs
[i
].ce_blockmode
;
787 ce_method
= ce
->variant
->op_mode
[id
];
788 if (ce_method
== CE_ID_NOTSUPP
) {
789 dev_dbg(ce
->dev
, "DEBUG: Blockmode of %s not supported\n",
790 ce_algs
[i
].alg
.skcipher
.base
.cra_name
);
791 ce_algs
[i
].ce
= NULL
;
794 dev_info(ce
->dev
, "Register %s\n",
795 ce_algs
[i
].alg
.skcipher
.base
.cra_name
);
796 err
= crypto_register_skcipher(&ce_algs
[i
].alg
.skcipher
);
798 dev_err(ce
->dev
, "ERROR: Fail to register %s\n",
799 ce_algs
[i
].alg
.skcipher
.base
.cra_name
);
800 ce_algs
[i
].ce
= NULL
;
804 case CRYPTO_ALG_TYPE_AHASH
:
805 id
= ce_algs
[i
].ce_algo_id
;
806 ce_method
= ce
->variant
->alg_hash
[id
];
807 if (ce_method
== CE_ID_NOTSUPP
) {
809 "DEBUG: Algo of %s not supported\n",
810 ce_algs
[i
].alg
.hash
.halg
.base
.cra_name
);
811 ce_algs
[i
].ce
= NULL
;
814 dev_info(ce
->dev
, "Register %s\n",
815 ce_algs
[i
].alg
.hash
.halg
.base
.cra_name
);
816 err
= crypto_register_ahash(&ce_algs
[i
].alg
.hash
);
818 dev_err(ce
->dev
, "ERROR: Fail to register %s\n",
819 ce_algs
[i
].alg
.hash
.halg
.base
.cra_name
);
820 ce_algs
[i
].ce
= NULL
;
824 case CRYPTO_ALG_TYPE_RNG
:
825 if (ce
->variant
->prng
== CE_ID_NOTSUPP
) {
827 "DEBUG: Algo of %s not supported\n",
828 ce_algs
[i
].alg
.rng
.base
.cra_name
);
829 ce_algs
[i
].ce
= NULL
;
832 dev_info(ce
->dev
, "Register %s\n",
833 ce_algs
[i
].alg
.rng
.base
.cra_name
);
834 err
= crypto_register_rng(&ce_algs
[i
].alg
.rng
);
836 dev_err(ce
->dev
, "Fail to register %s\n",
837 ce_algs
[i
].alg
.rng
.base
.cra_name
);
838 ce_algs
[i
].ce
= NULL
;
842 ce_algs
[i
].ce
= NULL
;
843 dev_err(ce
->dev
, "ERROR: tried to register an unknown algo\n");
849 static void sun8i_ce_unregister_algs(struct sun8i_ce_dev
*ce
)
853 for (i
= 0; i
< ARRAY_SIZE(ce_algs
); i
++) {
856 switch (ce_algs
[i
].type
) {
857 case CRYPTO_ALG_TYPE_SKCIPHER
:
858 dev_info(ce
->dev
, "Unregister %d %s\n", i
,
859 ce_algs
[i
].alg
.skcipher
.base
.cra_name
);
860 crypto_unregister_skcipher(&ce_algs
[i
].alg
.skcipher
);
862 case CRYPTO_ALG_TYPE_AHASH
:
863 dev_info(ce
->dev
, "Unregister %d %s\n", i
,
864 ce_algs
[i
].alg
.hash
.halg
.base
.cra_name
);
865 crypto_unregister_ahash(&ce_algs
[i
].alg
.hash
);
867 case CRYPTO_ALG_TYPE_RNG
:
868 dev_info(ce
->dev
, "Unregister %d %s\n", i
,
869 ce_algs
[i
].alg
.rng
.base
.cra_name
);
870 crypto_unregister_rng(&ce_algs
[i
].alg
.rng
);
876 static int sun8i_ce_probe(struct platform_device
*pdev
)
878 struct sun8i_ce_dev
*ce
;
882 ce
= devm_kzalloc(&pdev
->dev
, sizeof(*ce
), GFP_KERNEL
);
886 ce
->dev
= &pdev
->dev
;
887 platform_set_drvdata(pdev
, ce
);
889 ce
->variant
= of_device_get_match_data(&pdev
->dev
);
891 dev_err(&pdev
->dev
, "Missing Crypto Engine variant\n");
895 ce
->base
= devm_platform_ioremap_resource(pdev
, 0);
896 if (IS_ERR(ce
->base
))
897 return PTR_ERR(ce
->base
);
899 err
= sun8i_ce_get_clks(ce
);
903 /* Get Non Secure IRQ */
904 irq
= platform_get_irq(pdev
, 0);
908 ce
->reset
= devm_reset_control_get(&pdev
->dev
, NULL
);
909 if (IS_ERR(ce
->reset
))
910 return dev_err_probe(&pdev
->dev
, PTR_ERR(ce
->reset
),
911 "No reset control found\n");
913 mutex_init(&ce
->mlock
);
914 mutex_init(&ce
->rnglock
);
916 err
= sun8i_ce_allocate_chanlist(ce
);
920 err
= sun8i_ce_pm_init(ce
);
924 err
= devm_request_irq(&pdev
->dev
, irq
, ce_irq_handler
, 0,
927 dev_err(ce
->dev
, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err
);
931 err
= sun8i_ce_register_algs(ce
);
935 err
= pm_runtime_get_sync(ce
->dev
);
939 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
940 sun8i_ce_hwrng_register(ce
);
943 v
= readl(ce
->base
+ CE_CTR
);
944 v
>>= CE_DIE_ID_SHIFT
;
946 dev_info(&pdev
->dev
, "CryptoEngine Die ID %x\n", v
);
948 pm_runtime_put_sync(ce
->dev
);
950 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
951 /* Ignore error of debugfs */
952 ce
->dbgfs_dir
= debugfs_create_dir("sun8i-ce", NULL
);
953 ce
->dbgfs_stats
= debugfs_create_file("stats", 0444,
955 &sun8i_ce_debugfs_fops
);
960 sun8i_ce_unregister_algs(ce
);
962 sun8i_ce_pm_exit(ce
);
964 sun8i_ce_free_chanlist(ce
, MAXFLOW
- 1);
968 static int sun8i_ce_remove(struct platform_device
*pdev
)
970 struct sun8i_ce_dev
*ce
= platform_get_drvdata(pdev
);
972 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
973 sun8i_ce_hwrng_unregister(ce
);
976 sun8i_ce_unregister_algs(ce
);
978 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
979 debugfs_remove_recursive(ce
->dbgfs_dir
);
982 sun8i_ce_free_chanlist(ce
, MAXFLOW
- 1);
984 sun8i_ce_pm_exit(ce
);
988 static const struct of_device_id sun8i_ce_crypto_of_match_table
[] = {
989 { .compatible
= "allwinner,sun8i-h3-crypto",
990 .data
= &ce_h3_variant
},
991 { .compatible
= "allwinner,sun8i-r40-crypto",
992 .data
= &ce_r40_variant
},
993 { .compatible
= "allwinner,sun50i-a64-crypto",
994 .data
= &ce_a64_variant
},
995 { .compatible
= "allwinner,sun50i-h5-crypto",
996 .data
= &ce_h5_variant
},
997 { .compatible
= "allwinner,sun50i-h6-crypto",
998 .data
= &ce_h6_variant
},
1001 MODULE_DEVICE_TABLE(of
, sun8i_ce_crypto_of_match_table
);
1003 static struct platform_driver sun8i_ce_driver
= {
1004 .probe
= sun8i_ce_probe
,
1005 .remove
= sun8i_ce_remove
,
1008 .pm
= &sun8i_ce_pm_ops
,
1009 .of_match_table
= sun8i_ce_crypto_of_match_table
,
1013 module_platform_driver(sun8i_ce_driver
);
1015 MODULE_DESCRIPTION("Allwinner Crypto Engine cryptographic offloader");
1016 MODULE_LICENSE("GPL");
1017 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");