GNU Linux-libre 5.16.19-gnu
[releases.git] / drivers / crypto / allwinner / sun8i-ce / sun8i-ce-core.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * sun8i-ce-core.c - hardware cryptographic offloader for
4  * Allwinner H3/A64/H5/H2+/H6/R40 SoC
5  *
6  * Copyright (C) 2015-2019 Corentin Labbe <clabbe.montjoie@gmail.com>
7  *
8  * Core file which registers crypto algorithms supported by the CryptoEngine.
9  *
10  * You could find a link for the datasheet in Documentation/arm/sunxi.rst
11  */
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>
17 #include <linux/io.h>
18 #include <linux/irq.h>
19 #include <linux/module.h>
20 #include <linux/of.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>
27
28 #include "sun8i-ce.h"
29
30 /*
31  * mod clock is lower on H3 than other SoC due to some DMA timeout occurring
32  * with high value.
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)
35  */
36 static const struct ce_variant ce_h3_variant = {
37         .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
38         },
39         .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
40                 CE_ALG_SHA384, CE_ALG_SHA512
41         },
42         .op_mode = { CE_OP_ECB, CE_OP_CBC
43         },
44         .ce_clks = {
45                 { "bus", 0, 200000000 },
46                 { "mod", 50000000, 0 },
47                 },
48         .esr = ESR_H3,
49         .prng = CE_ALG_PRNG,
50         .trng = CE_ID_NOTSUPP,
51 };
52
53 static const struct ce_variant ce_h5_variant = {
54         .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
55         },
56         .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
57                 CE_ID_NOTSUPP, CE_ID_NOTSUPP
58         },
59         .op_mode = { CE_OP_ECB, CE_OP_CBC
60         },
61         .ce_clks = {
62                 { "bus", 0, 200000000 },
63                 { "mod", 300000000, 0 },
64                 },
65         .esr = ESR_H5,
66         .prng = CE_ALG_PRNG,
67         .trng = CE_ID_NOTSUPP,
68 };
69
70 static const struct ce_variant ce_h6_variant = {
71         .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
72         },
73         .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
74                 CE_ALG_SHA384, CE_ALG_SHA512
75         },
76         .op_mode = { CE_OP_ECB, CE_OP_CBC
77         },
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,
82         .ce_clks = {
83                 { "bus", 0, 200000000 },
84                 { "mod", 300000000, 0 },
85                 { "ram", 0, 400000000 },
86                 },
87         .esr = ESR_H6,
88         .prng = CE_ALG_PRNG_V2,
89         .trng = CE_ALG_TRNG_V2,
90 };
91
92 static const struct ce_variant ce_a64_variant = {
93         .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
94         },
95         .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
96                 CE_ID_NOTSUPP, CE_ID_NOTSUPP
97         },
98         .op_mode = { CE_OP_ECB, CE_OP_CBC
99         },
100         .ce_clks = {
101                 { "bus", 0, 200000000 },
102                 { "mod", 300000000, 0 },
103                 },
104         .esr = ESR_A64,
105         .prng = CE_ALG_PRNG,
106         .trng = CE_ID_NOTSUPP,
107 };
108
109 static const struct ce_variant ce_r40_variant = {
110         .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
111         },
112         .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
113                 CE_ID_NOTSUPP, CE_ID_NOTSUPP
114         },
115         .op_mode = { CE_OP_ECB, CE_OP_CBC
116         },
117         .ce_clks = {
118                 { "bus", 0, 200000000 },
119                 { "mod", 300000000, 0 },
120                 },
121         .esr = ESR_R40,
122         .prng = CE_ALG_PRNG,
123         .trng = CE_ID_NOTSUPP,
124 };
125
126 /*
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
130  */
131 int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce)
132 {
133         return atomic_inc_return(&ce->flow) % (MAXFLOW - 1);
134 }
135
136 int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name)
137 {
138         u32 v;
139         int err = 0;
140         struct ce_task *cet = ce->chanlist[flow].tl;
141
142 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
143         ce->chanlist[flow].stat_req++;
144 #endif
145
146         mutex_lock(&ce->mlock);
147
148         v = readl(ce->base + CE_ICR);
149         v |= 1 << flow;
150         writel(v, ce->base + CE_ICR);
151
152         reinit_completion(&ce->chanlist[flow].complete);
153         writel(ce->chanlist[flow].t_phy, ce->base + CE_TDQ);
154
155         ce->chanlist[flow].status = 0;
156         /* Be sure all data is written before enabling the task */
157         wmb();
158
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.
161          */
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);
165
166         wait_for_completion_interruptible_timeout(&ce->chanlist[flow].complete,
167                         msecs_to_jiffies(ce->chanlist[flow].timeout));
168
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);
172                 err = -EFAULT;
173         }
174         /* No need to lock for this read, the channel is locked so
175          * nothing could modify the error value for this channel
176          */
177         v = readl(ce->base + CE_ESR);
178         switch (ce->variant->esr) {
179         case ESR_H3:
180                 /* Sadly, the error bit is not per flow */
181                 if (v) {
182                         dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
183                         err = -EFAULT;
184                         print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4,
185                                        cet, sizeof(struct ce_task), false);
186                 }
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");
193                 break;
194         case ESR_A64:
195         case ESR_H5:
196         case ESR_R40:
197                 v >>= (flow * 4);
198                 v &= 0xF;
199                 if (v) {
200                         dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
201                         err = -EFAULT;
202                         print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4,
203                                        cet, sizeof(struct ce_task), false);
204                 }
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");
211                 break;
212         case ESR_H6:
213                 v >>= (flow * 8);
214                 v &= 0xFF;
215                 if (v) {
216                         dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
217                         err = -EFAULT;
218                         print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4,
219                                        cet, sizeof(struct ce_task), false);
220                 }
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");
231                 break;
232         }
233
234         return err;
235 }
236
237 static irqreturn_t ce_irq_handler(int irq, void *data)
238 {
239         struct sun8i_ce_dev *ce = (struct sun8i_ce_dev *)data;
240         int flow = 0;
241         u32 p;
242
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);
249                 }
250         }
251
252         return IRQ_HANDLED;
253 }
254
255 static struct sun8i_ce_alg_template ce_algs[] = {
256 {
257         .type = CRYPTO_ALG_TYPE_SKCIPHER,
258         .ce_algo_id = CE_ID_CIPHER_AES,
259         .ce_blockmode = CE_ID_OP_CBC,
260         .alg.skcipher = {
261                 .base = {
262                         .cra_name = "cbc(aes)",
263                         .cra_driver_name = "cbc-aes-sun8i-ce",
264                         .cra_priority = 400,
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,
274                 },
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,
281         }
282 },
283 {
284         .type = CRYPTO_ALG_TYPE_SKCIPHER,
285         .ce_algo_id = CE_ID_CIPHER_AES,
286         .ce_blockmode = CE_ID_OP_ECB,
287         .alg.skcipher = {
288                 .base = {
289                         .cra_name = "ecb(aes)",
290                         .cra_driver_name = "ecb-aes-sun8i-ce",
291                         .cra_priority = 400,
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,
301                 },
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,
307         }
308 },
309 {
310         .type = CRYPTO_ALG_TYPE_SKCIPHER,
311         .ce_algo_id = CE_ID_CIPHER_DES3,
312         .ce_blockmode = CE_ID_OP_CBC,
313         .alg.skcipher = {
314                 .base = {
315                         .cra_name = "cbc(des3_ede)",
316                         .cra_driver_name = "cbc-des3-sun8i-ce",
317                         .cra_priority = 400,
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,
327                 },
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,
334         }
335 },
336 {
337         .type = CRYPTO_ALG_TYPE_SKCIPHER,
338         .ce_algo_id = CE_ID_CIPHER_DES3,
339         .ce_blockmode = CE_ID_OP_ECB,
340         .alg.skcipher = {
341                 .base = {
342                         .cra_name = "ecb(des3_ede)",
343                         .cra_driver_name = "ecb-des3-sun8i-ce",
344                         .cra_priority = 400,
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,
354                 },
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,
360         }
361 },
362 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_HASH
363 {       .type = CRYPTO_ALG_TYPE_AHASH,
364         .ce_algo_id = CE_ID_HASH_MD5,
365         .alg.hash = {
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,
373                 .halg = {
374                         .digestsize = MD5_DIGEST_SIZE,
375                         .statesize = sizeof(struct md5_state),
376                         .base = {
377                                 .cra_name = "md5",
378                                 .cra_driver_name = "md5-sun8i-ce",
379                                 .cra_priority = 300,
380                                 .cra_alignmask = 3,
381                                 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
382                                         CRYPTO_ALG_ASYNC |
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,
389                         }
390                 }
391         }
392 },
393 {       .type = CRYPTO_ALG_TYPE_AHASH,
394         .ce_algo_id = CE_ID_HASH_SHA1,
395         .alg.hash = {
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,
403                 .halg = {
404                         .digestsize = SHA1_DIGEST_SIZE,
405                         .statesize = sizeof(struct sha1_state),
406                         .base = {
407                                 .cra_name = "sha1",
408                                 .cra_driver_name = "sha1-sun8i-ce",
409                                 .cra_priority = 300,
410                                 .cra_alignmask = 3,
411                                 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
412                                         CRYPTO_ALG_ASYNC |
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,
419                         }
420                 }
421         }
422 },
423 {       .type = CRYPTO_ALG_TYPE_AHASH,
424         .ce_algo_id = CE_ID_HASH_SHA224,
425         .alg.hash = {
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,
433                 .halg = {
434                         .digestsize = SHA224_DIGEST_SIZE,
435                         .statesize = sizeof(struct sha256_state),
436                         .base = {
437                                 .cra_name = "sha224",
438                                 .cra_driver_name = "sha224-sun8i-ce",
439                                 .cra_priority = 300,
440                                 .cra_alignmask = 3,
441                                 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
442                                         CRYPTO_ALG_ASYNC |
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,
449                         }
450                 }
451         }
452 },
453 {       .type = CRYPTO_ALG_TYPE_AHASH,
454         .ce_algo_id = CE_ID_HASH_SHA256,
455         .alg.hash = {
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,
463                 .halg = {
464                         .digestsize = SHA256_DIGEST_SIZE,
465                         .statesize = sizeof(struct sha256_state),
466                         .base = {
467                                 .cra_name = "sha256",
468                                 .cra_driver_name = "sha256-sun8i-ce",
469                                 .cra_priority = 300,
470                                 .cra_alignmask = 3,
471                                 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
472                                         CRYPTO_ALG_ASYNC |
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,
479                         }
480                 }
481         }
482 },
483 {       .type = CRYPTO_ALG_TYPE_AHASH,
484         .ce_algo_id = CE_ID_HASH_SHA384,
485         .alg.hash = {
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,
493                 .halg = {
494                         .digestsize = SHA384_DIGEST_SIZE,
495                         .statesize = sizeof(struct sha512_state),
496                         .base = {
497                                 .cra_name = "sha384",
498                                 .cra_driver_name = "sha384-sun8i-ce",
499                                 .cra_priority = 300,
500                                 .cra_alignmask = 3,
501                                 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
502                                         CRYPTO_ALG_ASYNC |
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,
509                         }
510                 }
511         }
512 },
513 {       .type = CRYPTO_ALG_TYPE_AHASH,
514         .ce_algo_id = CE_ID_HASH_SHA512,
515         .alg.hash = {
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,
523                 .halg = {
524                         .digestsize = SHA512_DIGEST_SIZE,
525                         .statesize = sizeof(struct sha512_state),
526                         .base = {
527                                 .cra_name = "sha512",
528                                 .cra_driver_name = "sha512-sun8i-ce",
529                                 .cra_priority = 300,
530                                 .cra_alignmask = 3,
531                                 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
532                                         CRYPTO_ALG_ASYNC |
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,
539                         }
540                 }
541         }
542 },
543 #endif
544 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
545 {
546         .type = CRYPTO_ALG_TYPE_RNG,
547         .alg.rng = {
548                 .base = {
549                         .cra_name               = "stdrng",
550                         .cra_driver_name        = "sun8i-ce-prng",
551                         .cra_priority           = 300,
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,
556                 },
557                 .generate               = sun8i_ce_prng_generate,
558                 .seed                   = sun8i_ce_prng_seed,
559                 .seedsize               = PRNG_SEED_SIZE,
560         }
561 },
562 #endif
563 };
564
565 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
566 static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v)
567 {
568         struct sun8i_ce_dev *ce = seq->private;
569         unsigned int i;
570
571         for (i = 0; i < MAXFLOW; i++)
572                 seq_printf(seq, "Channel %d: nreq %lu\n", i, ce->chanlist[i].stat_req);
573
574         for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
575                 if (!ce_algs[i].ce)
576                         continue;
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);
583                         break;
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);
589                         break;
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);
595                         break;
596                 }
597         }
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);
601 #endif
602         return 0;
603 }
604
605 DEFINE_SHOW_ATTRIBUTE(sun8i_ce_debugfs);
606 #endif
607
608 static void sun8i_ce_free_chanlist(struct sun8i_ce_dev *ce, int i)
609 {
610         while (i >= 0) {
611                 crypto_engine_exit(ce->chanlist[i].engine);
612                 if (ce->chanlist[i].tl)
613                         dma_free_coherent(ce->dev, sizeof(struct ce_task),
614                                           ce->chanlist[i].tl,
615                                           ce->chanlist[i].t_phy);
616                 i--;
617         }
618 }
619
620 /*
621  * Allocate the channel list structure
622  */
623 static int sun8i_ce_allocate_chanlist(struct sun8i_ce_dev *ce)
624 {
625         int i, err;
626
627         ce->chanlist = devm_kcalloc(ce->dev, MAXFLOW,
628                                     sizeof(struct sun8i_ce_flow), GFP_KERNEL);
629         if (!ce->chanlist)
630                 return -ENOMEM;
631
632         for (i = 0; i < MAXFLOW; i++) {
633                 init_completion(&ce->chanlist[i].complete);
634
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");
638                         i--;
639                         err = -ENOMEM;
640                         goto error_engine;
641                 }
642                 err = crypto_engine_start(ce->chanlist[i].engine);
643                 if (err) {
644                         dev_err(ce->dev, "Cannot start engine\n");
645                         goto error_engine;
646                 }
647                 ce->chanlist[i].tl = dma_alloc_coherent(ce->dev,
648                                                         sizeof(struct ce_task),
649                                                         &ce->chanlist[i].t_phy,
650                                                         GFP_KERNEL);
651                 if (!ce->chanlist[i].tl) {
652                         dev_err(ce->dev, "Cannot get DMA memory for task %d\n",
653                                 i);
654                         err = -ENOMEM;
655                         goto error_engine;
656                 }
657         }
658         return 0;
659 error_engine:
660         sun8i_ce_free_chanlist(ce, i);
661         return err;
662 }
663
664 /*
665  * Power management strategy: The device is suspended unless a TFM exists for
666  * one of the algorithms proposed by this driver.
667  */
668 static int sun8i_ce_pm_suspend(struct device *dev)
669 {
670         struct sun8i_ce_dev *ce = dev_get_drvdata(dev);
671         int i;
672
673         reset_control_assert(ce->reset);
674         for (i = 0; i < CE_MAX_CLOCKS; i++)
675                 clk_disable_unprepare(ce->ceclks[i]);
676         return 0;
677 }
678
679 static int sun8i_ce_pm_resume(struct device *dev)
680 {
681         struct sun8i_ce_dev *ce = dev_get_drvdata(dev);
682         int err, i;
683
684         for (i = 0; i < CE_MAX_CLOCKS; i++) {
685                 if (!ce->variant->ce_clks[i].name)
686                         continue;
687                 err = clk_prepare_enable(ce->ceclks[i]);
688                 if (err) {
689                         dev_err(ce->dev, "Cannot prepare_enable %s\n",
690                                 ce->variant->ce_clks[i].name);
691                         goto error;
692                 }
693         }
694         err = reset_control_deassert(ce->reset);
695         if (err) {
696                 dev_err(ce->dev, "Cannot deassert reset control\n");
697                 goto error;
698         }
699         return 0;
700 error:
701         sun8i_ce_pm_suspend(dev);
702         return err;
703 }
704
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)
707 };
708
709 static int sun8i_ce_pm_init(struct sun8i_ce_dev *ce)
710 {
711         int err;
712
713         pm_runtime_use_autosuspend(ce->dev);
714         pm_runtime_set_autosuspend_delay(ce->dev, 2000);
715
716         err = pm_runtime_set_suspended(ce->dev);
717         if (err)
718                 return err;
719         pm_runtime_enable(ce->dev);
720         return err;
721 }
722
723 static void sun8i_ce_pm_exit(struct sun8i_ce_dev *ce)
724 {
725         pm_runtime_disable(ce->dev);
726 }
727
728 static int sun8i_ce_get_clks(struct sun8i_ce_dev *ce)
729 {
730         unsigned long cr;
731         int err, i;
732
733         for (i = 0; i < CE_MAX_CLOCKS; i++) {
734                 if (!ce->variant->ce_clks[i].name)
735                         continue;
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);
741                         return err;
742                 }
743                 cr = clk_get_rate(ce->ceclks[i]);
744                 if (!cr)
745                         return -EINVAL;
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,
752                                  cr, cr / 1000000);
753                         err = clk_set_rate(ce->ceclks[i], ce->variant->ce_clks[i].freq);
754                         if (err)
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);
758                 }
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);
764         }
765         return 0;
766 }
767
768 static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce)
769 {
770         int ce_method, err, id;
771         unsigned int i;
772
773         for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
774                 ce_algs[i].ce = ce;
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) {
780                                 dev_dbg(ce->dev,
781                                         "DEBUG: Algo of %s not supported\n",
782                                         ce_algs[i].alg.skcipher.base.cra_name);
783                                 ce_algs[i].ce = NULL;
784                                 break;
785                         }
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;
792                                 break;
793                         }
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);
797                         if (err) {
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;
801                                 return err;
802                         }
803                         break;
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) {
808                                 dev_info(ce->dev,
809                                          "DEBUG: Algo of %s not supported\n",
810                                          ce_algs[i].alg.hash.halg.base.cra_name);
811                                 ce_algs[i].ce = NULL;
812                                 break;
813                         }
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);
817                         if (err) {
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;
821                                 return err;
822                         }
823                         break;
824                 case CRYPTO_ALG_TYPE_RNG:
825                         if (ce->variant->prng == CE_ID_NOTSUPP) {
826                                 dev_info(ce->dev,
827                                          "DEBUG: Algo of %s not supported\n",
828                                          ce_algs[i].alg.rng.base.cra_name);
829                                 ce_algs[i].ce = NULL;
830                                 break;
831                         }
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);
835                         if (err) {
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;
839                         }
840                         break;
841                 default:
842                         ce_algs[i].ce = NULL;
843                         dev_err(ce->dev, "ERROR: tried to register an unknown algo\n");
844                 }
845         }
846         return 0;
847 }
848
849 static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce)
850 {
851         unsigned int i;
852
853         for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
854                 if (!ce_algs[i].ce)
855                         continue;
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);
861                         break;
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);
866                         break;
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);
871                         break;
872                 }
873         }
874 }
875
876 static int sun8i_ce_probe(struct platform_device *pdev)
877 {
878         struct sun8i_ce_dev *ce;
879         int err, irq;
880         u32 v;
881
882         ce = devm_kzalloc(&pdev->dev, sizeof(*ce), GFP_KERNEL);
883         if (!ce)
884                 return -ENOMEM;
885
886         ce->dev = &pdev->dev;
887         platform_set_drvdata(pdev, ce);
888
889         ce->variant = of_device_get_match_data(&pdev->dev);
890         if (!ce->variant) {
891                 dev_err(&pdev->dev, "Missing Crypto Engine variant\n");
892                 return -EINVAL;
893         }
894
895         ce->base = devm_platform_ioremap_resource(pdev, 0);
896         if (IS_ERR(ce->base))
897                 return PTR_ERR(ce->base);
898
899         err = sun8i_ce_get_clks(ce);
900         if (err)
901                 return err;
902
903         /* Get Non Secure IRQ */
904         irq = platform_get_irq(pdev, 0);
905         if (irq < 0)
906                 return irq;
907
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");
912
913         mutex_init(&ce->mlock);
914         mutex_init(&ce->rnglock);
915
916         err = sun8i_ce_allocate_chanlist(ce);
917         if (err)
918                 return err;
919
920         err = sun8i_ce_pm_init(ce);
921         if (err)
922                 goto error_pm;
923
924         err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0,
925                                "sun8i-ce-ns", ce);
926         if (err) {
927                 dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err);
928                 goto error_irq;
929         }
930
931         err = sun8i_ce_register_algs(ce);
932         if (err)
933                 goto error_alg;
934
935         err = pm_runtime_resume_and_get(ce->dev);
936         if (err < 0)
937                 goto error_alg;
938
939 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
940         sun8i_ce_hwrng_register(ce);
941 #endif
942
943         v = readl(ce->base + CE_CTR);
944         v >>= CE_DIE_ID_SHIFT;
945         v &= CE_DIE_ID_MASK;
946         dev_info(&pdev->dev, "CryptoEngine Die ID %x\n", v);
947
948         pm_runtime_put_sync(ce->dev);
949
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,
954                                               ce->dbgfs_dir, ce,
955                                               &sun8i_ce_debugfs_fops);
956 #endif
957
958         return 0;
959 error_alg:
960         sun8i_ce_unregister_algs(ce);
961 error_irq:
962         sun8i_ce_pm_exit(ce);
963 error_pm:
964         sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
965         return err;
966 }
967
968 static int sun8i_ce_remove(struct platform_device *pdev)
969 {
970         struct sun8i_ce_dev *ce = platform_get_drvdata(pdev);
971
972 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
973         sun8i_ce_hwrng_unregister(ce);
974 #endif
975
976         sun8i_ce_unregister_algs(ce);
977
978 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
979         debugfs_remove_recursive(ce->dbgfs_dir);
980 #endif
981
982         sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
983
984         sun8i_ce_pm_exit(ce);
985         return 0;
986 }
987
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 },
999         {}
1000 };
1001 MODULE_DEVICE_TABLE(of, sun8i_ce_crypto_of_match_table);
1002
1003 static struct platform_driver sun8i_ce_driver = {
1004         .probe           = sun8i_ce_probe,
1005         .remove          = sun8i_ce_remove,
1006         .driver          = {
1007                 .name           = "sun8i-ce",
1008                 .pm             = &sun8i_ce_pm_ops,
1009                 .of_match_table = sun8i_ce_crypto_of_match_table,
1010         },
1011 };
1012
1013 module_platform_driver(sun8i_ce_driver);
1014
1015 MODULE_DESCRIPTION("Allwinner Crypto Engine cryptographic offloader");
1016 MODULE_LICENSE("GPL");
1017 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");