Commit d6e0fdcde5773fed4804cdacf927808bd2da3d7d
Committed by
faqiang.zhu
1 parent
89ff2dcb74
Exists in
smarc_8mm-imx_v2019.04_4.19.35_1.1.0
and in
1 other branch
MA-13937 Enable CAAM for imx8q
The CAAM driver in u-boot will use JR0 by default, but for imx8q, both JR0 and JR1 are assigned to SECO and A core should never access them. Power on the JR3 in this patchset and use it to complete the CAAM operations for imx8q. Test: CAAM self test cases pass for imx8q. below patches are merged to this commit: MA-13964 imx8q: Kick the CAAM JR before kicking the SMMU MA-13969 Fix CAAM build warnings Change-Id: Ie3d77d1f2910e7f4c257c797c12b5c8a30ad936a Signed-off-by: Ji Luo <ji.luo@nxp.com>
Showing 5 changed files with 327 additions and 228 deletions Side-by-side Diff
arch/arm/include/asm/arch-imx8/crm_regs.h
board/freescale/imx8qm_mek/imx8qm_mek.c
... | ... | @@ -88,6 +88,14 @@ |
88 | 88 | |
89 | 89 | setup_iomux_uart(); |
90 | 90 | |
91 | +/* Dual bootloader feature will require CAAM access, but JR0 and JR1 will be | |
92 | + * assigned to seco for imx8, use JR3 instead. | |
93 | + */ | |
94 | +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_DUAL_BOOTLOADER) | |
95 | + sc_pm_set_resource_power_mode(-1, SC_R_CAAM_JR3, SC_PM_PW_MODE_ON); | |
96 | + sc_pm_set_resource_power_mode(-1, SC_R_CAAM_JR3_OUT, SC_PM_PW_MODE_ON); | |
97 | +#endif | |
98 | + | |
91 | 99 | return 0; |
92 | 100 | } |
93 | 101 |
board/freescale/imx8qxp_mek/imx8qxp_mek.c
... | ... | @@ -77,6 +77,14 @@ |
77 | 77 | |
78 | 78 | setup_iomux_uart(); |
79 | 79 | |
80 | +/* Dual bootloader feature will require CAAM access, but JR0 and JR1 will be | |
81 | + * assigned to seco for imx8, use JR3 instead. | |
82 | + */ | |
83 | +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_DUAL_BOOTLOADER) | |
84 | + sc_pm_set_resource_power_mode(-1, SC_R_CAAM_JR3, SC_PM_PW_MODE_ON); | |
85 | + sc_pm_set_resource_power_mode(-1, SC_R_CAAM_JR3_OUT, SC_PM_PW_MODE_ON); | |
86 | +#endif | |
87 | + | |
80 | 88 | return 0; |
81 | 89 | } |
82 | 90 |
drivers/crypto/fsl_caam.c
... | ... | @@ -44,12 +44,16 @@ |
44 | 44 | |
45 | 45 | DECLARE_GLOBAL_DATA_PTR; |
46 | 46 | |
47 | -static void rng_init(void); | |
48 | -static void caam_clock_enable(void); | |
49 | 47 | static int do_cfg_jrqueue(void); |
50 | 48 | static int do_job(u32 *desc); |
49 | +#ifndef CONFIG_ARCH_IMX8 | |
50 | +static void rng_init(void); | |
51 | +static void caam_clock_enable(void); | |
51 | 52 | static int jr_reset(void); |
53 | +#endif | |
54 | +#ifdef CONFIG_CAAM_KB_SELF_TEST | |
52 | 55 | static void caam_test(void); |
56 | +#endif | |
53 | 57 | |
54 | 58 | /* |
55 | 59 | * Structures |
56 | 60 | |
57 | 61 | |
58 | 62 | |
... | ... | @@ -250,13 +254,16 @@ |
250 | 254 | */ |
251 | 255 | void caam_open(void) |
252 | 256 | { |
253 | - u32 temp_reg; | |
254 | 257 | int ret; |
255 | 258 | |
256 | 259 | /* switch on the clock */ |
260 | + /* for imx8, the CAAM initialization should have been done | |
261 | + * in seco, so we should skip this part. | |
262 | + */ | |
257 | 263 | #ifndef CONFIG_ARCH_IMX8 |
264 | + u32 temp_reg; | |
265 | + | |
258 | 266 | caam_clock_enable(); |
259 | -#endif | |
260 | 267 | |
261 | 268 | /* reset the CAAM */ |
262 | 269 | temp_reg = __raw_readl(CAAM_MCFGR) | |
... | ... | @@ -266,6 +273,7 @@ |
266 | 273 | ; |
267 | 274 | |
268 | 275 | jr_reset(); |
276 | + | |
269 | 277 | ret = do_cfg_jrqueue(); |
270 | 278 | |
271 | 279 | if (ret != SUCCESS) { |
272 | 280 | |
273 | 281 | |
274 | 282 | |
... | ... | @@ -279,138 +287,21 @@ |
279 | 287 | printf("RNG already instantiated 0x%X\n", temp_reg); |
280 | 288 | return; |
281 | 289 | } |
282 | - | |
283 | 290 | rng_init(); |
291 | +#else | |
292 | + ret = do_cfg_jrqueue(); | |
284 | 293 | |
294 | + if (ret != SUCCESS) { | |
295 | + printf("Error CAAM JR initialization\n"); | |
296 | + return; | |
297 | + } | |
298 | +#endif | |
299 | + | |
285 | 300 | #ifdef CONFIG_CAAM_KB_SELF_TEST |
286 | 301 | caam_test(); |
287 | 302 | #endif |
288 | 303 | } |
289 | 304 | |
290 | -static void caam_clock_enable(void) | |
291 | -{ | |
292 | -#if defined(CONFIG_ARCH_MX6) | |
293 | - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; | |
294 | - u32 reg; | |
295 | - | |
296 | - reg = __raw_readl(&mxc_ccm->CCGR0); | |
297 | - | |
298 | - reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK | | |
299 | - MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | | |
300 | - MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK); | |
301 | - | |
302 | - __raw_writel(reg, &mxc_ccm->CCGR0); | |
303 | - | |
304 | -#ifndef CONFIG_MX6UL | |
305 | - /* EMI slow clk */ | |
306 | - reg = __raw_readl(&mxc_ccm->CCGR6); | |
307 | - reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; | |
308 | - | |
309 | - __raw_writel(reg, &mxc_ccm->CCGR6); | |
310 | -#endif | |
311 | - | |
312 | -#elif defined(CONFIG_ARCH_MX7) | |
313 | - HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK); | |
314 | -#elif defined(CONFIG_ARCH_MX7ULP) | |
315 | - pcc_clock_enable(PER_CLK_CAAM, true); | |
316 | -#endif | |
317 | -} | |
318 | - | |
319 | -static void kick_trng(u32 ent_delay) | |
320 | -{ | |
321 | - u32 samples = 512; /* number of bits to generate and test */ | |
322 | - u32 mono_min = 195; | |
323 | - u32 mono_max = 317; | |
324 | - u32 mono_range = mono_max - mono_min; | |
325 | - u32 poker_min = 1031; | |
326 | - u32 poker_max = 1600; | |
327 | - u32 poker_range = poker_max - poker_min + 1; | |
328 | - u32 retries = 2; | |
329 | - u32 lrun_max = 32; | |
330 | - s32 run_1_min = 27; | |
331 | - s32 run_1_max = 107; | |
332 | - s32 run_1_range = run_1_max - run_1_min; | |
333 | - s32 run_2_min = 7; | |
334 | - s32 run_2_max = 62; | |
335 | - s32 run_2_range = run_2_max - run_2_min; | |
336 | - s32 run_3_min = 0; | |
337 | - s32 run_3_max = 39; | |
338 | - s32 run_3_range = run_3_max - run_3_min; | |
339 | - s32 run_4_min = -1; | |
340 | - s32 run_4_max = 26; | |
341 | - s32 run_4_range = run_4_max - run_4_min; | |
342 | - s32 run_5_min = -1; | |
343 | - s32 run_5_max = 18; | |
344 | - s32 run_5_range = run_5_max - run_5_min; | |
345 | - s32 run_6_min = -1; | |
346 | - s32 run_6_max = 17; | |
347 | - s32 run_6_range = run_6_max - run_6_min; | |
348 | - u32 val; | |
349 | - | |
350 | - /* Put RNG in program mode */ | |
351 | - /* Setting both RTMCTL:PRGM and RTMCTL:TRNG_ACC causes TRNG to | |
352 | - * properly invalidate the entropy in the entropy register and | |
353 | - * force re-generation. | |
354 | - */ | |
355 | - setbits_le32(CAAM_RTMCTL, RTMCTL_PGM | RTMCTL_ACC); | |
356 | - | |
357 | - /* Configure the RNG Entropy Delay | |
358 | - * Performance-wise, it does not make sense to | |
359 | - * set the delay to a value that is lower | |
360 | - * than the last one that worked (i.e. the state handles | |
361 | - * were instantiated properly. Thus, instead of wasting | |
362 | - * time trying to set the values controlling the sample | |
363 | - * frequency, the function simply returns. | |
364 | - */ | |
365 | - val = __raw_readl(CAAM_RTSDCTL); | |
366 | - val &= BM_TRNG_ENT_DLY; | |
367 | - val >>= BS_TRNG_ENT_DLY; | |
368 | - if (ent_delay < val) { | |
369 | - /* Put RNG4 into run mode */ | |
370 | - clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM | RTMCTL_ACC); | |
371 | - return; | |
372 | - } | |
373 | - | |
374 | - val = (ent_delay << BS_TRNG_ENT_DLY) | samples; | |
375 | - __raw_writel(val, CAAM_RTSDCTL); | |
376 | - | |
377 | - /* min. freq. count, equal to 1/2 of the entropy sample length */ | |
378 | - __raw_writel(ent_delay >> 1, CAAM_RTFRQMIN); | |
379 | - | |
380 | - /* max. freq. count, equal to 32 times the entropy sample length */ | |
381 | - __raw_writel(ent_delay << 5, CAAM_RTFRQMAX); | |
382 | - | |
383 | - __raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC); | |
384 | - __raw_writel(poker_max, CAAM_RTPKRMAX); | |
385 | - __raw_writel(poker_range, CAAM_RTPKRRNG); | |
386 | - __raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML); | |
387 | - __raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L); | |
388 | - __raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L); | |
389 | - __raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L); | |
390 | - __raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L); | |
391 | - __raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L); | |
392 | - __raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL); | |
393 | - | |
394 | - val = __raw_readl(CAAM_RTMCTL); | |
395 | - /* | |
396 | - * Select raw sampling in both entropy shifter | |
397 | - * and statistical checker | |
398 | - */ | |
399 | - val &= ~BM_TRNG_SAMP_MODE; | |
400 | - val |= TRNG_SAMP_MODE_RAW_ES_SC; | |
401 | - /* Put RNG4 into run mode */ | |
402 | - val &= ~(RTMCTL_PGM | RTMCTL_ACC); | |
403 | -/*test with sample mode only */ | |
404 | - __raw_writel(val, CAAM_RTMCTL); | |
405 | - | |
406 | - /* Clear the ERR bit in RTMCTL if set. The TRNG error can occur when the | |
407 | - * RNG clock is not within 1/2x to 8x the system clock. | |
408 | - * This error is possible if ROM code does not initialize the system PLLs | |
409 | - * immediately after PoR. | |
410 | - */ | |
411 | - /* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */ | |
412 | -} | |
413 | - | |
414 | 305 | /* |
415 | 306 | * Descriptors to instantiate SH0, SH1, load the keys |
416 | 307 | */ |
417 | 308 | |
418 | 309 | |
... | ... | @@ -444,110 +335,19 @@ |
444 | 335 | CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | ALGO_RNG_GENERATE, |
445 | 336 | }; |
446 | 337 | |
447 | -static void do_inst_desc(u32 *desc, u32 status) | |
448 | -{ | |
449 | - u32 *pdesc = desc; | |
450 | - u8 desc_len; | |
451 | - bool add_sh0 = false; | |
452 | - bool add_sh1 = false; | |
453 | - bool load_keys = false; | |
454 | - | |
455 | - /* | |
456 | - * Modify the the descriptor to remove if necessary: | |
457 | - * - The key loading | |
458 | - * - One of the SH already instantiated | |
459 | - */ | |
460 | - desc_len = RNG_DESC_SH0_SIZE; | |
461 | - if ((status & RDSTA_IF0) != RDSTA_IF0) | |
462 | - add_sh0 = true; | |
463 | - | |
464 | - if ((status & RDSTA_IF1) != RDSTA_IF1) { | |
465 | - add_sh1 = true; | |
466 | - if (add_sh0) | |
467 | - desc_len += RNG_DESC_SH1_SIZE; | |
468 | - } | |
469 | - | |
470 | - if ((status & RDSTA_SKVN) != RDSTA_SKVN) { | |
471 | - load_keys = true; | |
472 | - desc_len += RNG_DESC_KEYS_SIZE; | |
473 | - } | |
474 | - | |
475 | - /* Copy the SH0 descriptor anyway */ | |
476 | - memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc)); | |
477 | - pdesc += RNG_DESC_SH0_SIZE; | |
478 | - | |
479 | - if (load_keys) { | |
480 | - debug("RNG - Load keys\n"); | |
481 | - memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys)); | |
482 | - pdesc += RNG_DESC_KEYS_SIZE; | |
483 | - } | |
484 | - | |
485 | - if (add_sh1) { | |
486 | - if (add_sh0) { | |
487 | - debug("RNG - Instantiation of SH0 and SH1\n"); | |
488 | - /* Add the sh1 descriptor */ | |
489 | - memcpy(pdesc, rng_inst_sh1_desc, | |
490 | - sizeof(rng_inst_sh1_desc)); | |
491 | - } else { | |
492 | - debug("RNG - Instantiation of SH1 only\n"); | |
493 | - /* Modify the SH0 descriptor to instantiate only SH1 */ | |
494 | - desc[1] &= ~BM_ALGO_RNG_SH; | |
495 | - desc[1] |= ALGO_RNG_SH(1); | |
496 | - } | |
497 | - } | |
498 | - | |
499 | - /* Setup the descriptor size */ | |
500 | - desc[0] &= ~(0x3F); | |
501 | - desc[0] |= CAAM_HDR_DESCLEN(desc_len); | |
502 | -} | |
503 | - | |
504 | -static int jr_reset(void) | |
505 | -{ | |
506 | - /* | |
507 | - * Function reset the Job Ring HW | |
508 | - * Reset is done in 2 steps: | |
509 | - * - Flush all pending jobs (Set RESET bit) | |
510 | - * - Reset the Job Ring (Set RESET bit second time) | |
511 | - */ | |
512 | - u16 timeout = 10000; | |
513 | - u32 reg_val; | |
514 | - | |
515 | - /* Mask interrupts to poll for reset completion status */ | |
516 | - setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK); | |
517 | - | |
518 | - /* Initiate flush (required prior to reset) */ | |
519 | - __raw_writel(JRCR_RESET, CAAM_JRCR0); | |
520 | - do { | |
521 | - reg_val = __raw_readl(CAAM_JRINTR0); | |
522 | - reg_val &= BM_JRINTR_HALT; | |
523 | - } while ((reg_val == JRINTR_HALT_ONGOING) && --timeout); | |
524 | - | |
525 | - if (!timeout || reg_val != JRINTR_HALT_DONE) { | |
526 | - printf("Failed to flush job ring\n"); | |
527 | - return ERROR_ANY; | |
528 | - } | |
529 | - | |
530 | - /* Initiate reset */ | |
531 | - timeout = 100; | |
532 | - __raw_writel(JRCR_RESET, CAAM_JRCR0); | |
533 | - do { | |
534 | - reg_val = __raw_readl(CAAM_JRCR0); | |
535 | - } while ((reg_val & JRCR_RESET) && --timeout); | |
536 | - | |
537 | - if (!timeout) { | |
538 | - printf("Failed to reset job ring\n"); | |
539 | - return ERROR_ANY; | |
540 | - } | |
541 | - | |
542 | - return 0; | |
543 | -} | |
544 | - | |
545 | 338 | static int do_job(u32 *desc) |
546 | 339 | { |
547 | 340 | int ret; |
548 | 341 | phys_addr_t p_desc = virt_to_phys(desc); |
549 | 342 | |
343 | + /* for imx8, JR0 and JR1 will be assigned to seco, so we use | |
344 | + * the JR3 instead. | |
345 | + */ | |
346 | +#ifndef CONFIG_ARCH_IMX8 | |
550 | 347 | if (__raw_readl(CAAM_IRSAR0) == 0) |
348 | +#else | |
349 | + if (__raw_readl(CAAM_IRSAR3) == 0) | |
350 | +#endif | |
551 | 351 | return ERROR_ANY; |
552 | 352 | g_jrdata.inrings[0].desc = p_desc; |
553 | 353 | |
554 | 354 | |
... | ... | @@ -559,9 +359,15 @@ |
559 | 359 | + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN)); |
560 | 360 | |
561 | 361 | /* Inform HW that a new JR is available */ |
362 | +#ifndef CONFIG_ARCH_IMX8 | |
562 | 363 | __raw_writel(1, CAAM_IRJAR0); |
563 | 364 | while (__raw_readl(CAAM_ORSFR0) == 0) |
564 | 365 | ; |
366 | +#else | |
367 | + __raw_writel(1, CAAM_IRJAR3); | |
368 | + while (__raw_readl(CAAM_ORSFR3) == 0) | |
369 | + ; | |
370 | +#endif | |
565 | 371 | |
566 | 372 | flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK, |
567 | 373 | ((uintptr_t)g_jrdata.outrings & ALIGN_MASK) |
568 | 374 | |
569 | 375 | |
... | ... | @@ -575,10 +381,15 @@ |
575 | 381 | } |
576 | 382 | |
577 | 383 | /* Acknowledge interrupt */ |
384 | +#ifndef CONFIG_ARCH_IMX8 | |
578 | 385 | setbits_le32(CAAM_JRINTR0, JRINTR_JRI); |
579 | - | |
580 | 386 | /* Remove the JR from the output list even if no JR caller found */ |
581 | 387 | __raw_writel(1, CAAM_ORJRR0); |
388 | +#else | |
389 | + setbits_le32(CAAM_JRINTR3, JRINTR_JRI); | |
390 | + /* Remove the JR from the output list even if no JR caller found */ | |
391 | + __raw_writel(1, CAAM_ORJRR3); | |
392 | +#endif | |
582 | 393 | |
583 | 394 | return ret; |
584 | 395 | } |
... | ... | @@ -629,6 +440,11 @@ |
629 | 440 | /* Configure the HW Job Rings */ |
630 | 441 | ip_base = virt_to_phys((void *)g_jrdata.inrings); |
631 | 442 | op_base = virt_to_phys((void *)g_jrdata.outrings); |
443 | + | |
444 | + /* for imx8, JR0 and JR1 will be assigned to seco, so we use | |
445 | + * the JR3 instead. | |
446 | + */ | |
447 | +#ifndef CONFIG_ARCH_IMX8 | |
632 | 448 | __raw_writel(ip_base, CAAM_IRBAR0); |
633 | 449 | __raw_writel(1, CAAM_IRSR0); |
634 | 450 | |
635 | 451 | |
... | ... | @@ -636,7 +452,16 @@ |
636 | 452 | __raw_writel(1, CAAM_ORSR0); |
637 | 453 | |
638 | 454 | setbits_le32(CAAM_JRINTR0, JRINTR_JRI); |
455 | +#else | |
456 | + __raw_writel(ip_base, CAAM_IRBAR3); | |
457 | + __raw_writel(1, CAAM_IRSR3); | |
639 | 458 | |
459 | + __raw_writel(op_base, CAAM_ORBAR3); | |
460 | + __raw_writel(1, CAAM_ORSR3); | |
461 | + | |
462 | + setbits_le32(CAAM_JRINTR3, JRINTR_JRI); | |
463 | +#endif | |
464 | + | |
640 | 465 | /* |
641 | 466 | * Configure interrupts but disable it: |
642 | 467 | * Optimization to generate an interrupt either when there are |
643 | 468 | |
644 | 469 | |
... | ... | @@ -647,14 +472,19 @@ |
647 | 472 | value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT; |
648 | 473 | value |= BM_JRCFGR_LS_ICEN; |
649 | 474 | value |= BM_JRCFGR_LS_IMSK; |
475 | +#ifndef CONFIG_ARCH_IMX8 | |
650 | 476 | __raw_writel(value, CAAM_JRCFGR0_LS); |
651 | 477 | |
652 | 478 | /* Enable deco watchdog */ |
653 | 479 | setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE); |
480 | +#else | |
481 | + __raw_writel(value, CAAM_JRCFGR3_LS); | |
482 | +#endif | |
654 | 483 | |
655 | 484 | return 0; |
656 | 485 | } |
657 | 486 | |
487 | +#ifndef CONFIG_ARCH_IMX8 | |
658 | 488 | static void do_clear_rng_error(void) |
659 | 489 | { |
660 | 490 | u32 val; |
... | ... | @@ -667,6 +497,158 @@ |
667 | 497 | } |
668 | 498 | } |
669 | 499 | |
500 | +static void do_inst_desc(u32 *desc, u32 status) | |
501 | +{ | |
502 | + u32 *pdesc = desc; | |
503 | + u8 desc_len; | |
504 | + bool add_sh0 = false; | |
505 | + bool add_sh1 = false; | |
506 | + bool load_keys = false; | |
507 | + | |
508 | + /* | |
509 | + * Modify the the descriptor to remove if necessary: | |
510 | + * - The key loading | |
511 | + * - One of the SH already instantiated | |
512 | + */ | |
513 | + desc_len = RNG_DESC_SH0_SIZE; | |
514 | + if ((status & RDSTA_IF0) != RDSTA_IF0) | |
515 | + add_sh0 = true; | |
516 | + | |
517 | + if ((status & RDSTA_IF1) != RDSTA_IF1) { | |
518 | + add_sh1 = true; | |
519 | + if (add_sh0) | |
520 | + desc_len += RNG_DESC_SH1_SIZE; | |
521 | + } | |
522 | + | |
523 | + if ((status & RDSTA_SKVN) != RDSTA_SKVN) { | |
524 | + load_keys = true; | |
525 | + desc_len += RNG_DESC_KEYS_SIZE; | |
526 | + } | |
527 | + | |
528 | + /* Copy the SH0 descriptor anyway */ | |
529 | + memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc)); | |
530 | + pdesc += RNG_DESC_SH0_SIZE; | |
531 | + | |
532 | + if (load_keys) { | |
533 | + debug("RNG - Load keys\n"); | |
534 | + memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys)); | |
535 | + pdesc += RNG_DESC_KEYS_SIZE; | |
536 | + } | |
537 | + | |
538 | + if (add_sh1) { | |
539 | + if (add_sh0) { | |
540 | + debug("RNG - Instantiation of SH0 and SH1\n"); | |
541 | + /* Add the sh1 descriptor */ | |
542 | + memcpy(pdesc, rng_inst_sh1_desc, | |
543 | + sizeof(rng_inst_sh1_desc)); | |
544 | + } else { | |
545 | + debug("RNG - Instantiation of SH1 only\n"); | |
546 | + /* Modify the SH0 descriptor to instantiate only SH1 */ | |
547 | + desc[1] &= ~BM_ALGO_RNG_SH; | |
548 | + desc[1] |= ALGO_RNG_SH(1); | |
549 | + } | |
550 | + } | |
551 | + | |
552 | + /* Setup the descriptor size */ | |
553 | + desc[0] &= ~(0x3F); | |
554 | + desc[0] |= CAAM_HDR_DESCLEN(desc_len); | |
555 | +} | |
556 | + | |
557 | +static void kick_trng(u32 ent_delay) | |
558 | +{ | |
559 | + u32 samples = 512; /* number of bits to generate and test */ | |
560 | + u32 mono_min = 195; | |
561 | + u32 mono_max = 317; | |
562 | + u32 mono_range = mono_max - mono_min; | |
563 | + u32 poker_min = 1031; | |
564 | + u32 poker_max = 1600; | |
565 | + u32 poker_range = poker_max - poker_min + 1; | |
566 | + u32 retries = 2; | |
567 | + u32 lrun_max = 32; | |
568 | + s32 run_1_min = 27; | |
569 | + s32 run_1_max = 107; | |
570 | + s32 run_1_range = run_1_max - run_1_min; | |
571 | + s32 run_2_min = 7; | |
572 | + s32 run_2_max = 62; | |
573 | + s32 run_2_range = run_2_max - run_2_min; | |
574 | + s32 run_3_min = 0; | |
575 | + s32 run_3_max = 39; | |
576 | + s32 run_3_range = run_3_max - run_3_min; | |
577 | + s32 run_4_min = -1; | |
578 | + s32 run_4_max = 26; | |
579 | + s32 run_4_range = run_4_max - run_4_min; | |
580 | + s32 run_5_min = -1; | |
581 | + s32 run_5_max = 18; | |
582 | + s32 run_5_range = run_5_max - run_5_min; | |
583 | + s32 run_6_min = -1; | |
584 | + s32 run_6_max = 17; | |
585 | + s32 run_6_range = run_6_max - run_6_min; | |
586 | + u32 val; | |
587 | + | |
588 | + /* Put RNG in program mode */ | |
589 | + /* Setting both RTMCTL:PRGM and RTMCTL:TRNG_ACC causes TRNG to | |
590 | + * properly invalidate the entropy in the entropy register and | |
591 | + * force re-generation. | |
592 | + */ | |
593 | + setbits_le32(CAAM_RTMCTL, RTMCTL_PGM | RTMCTL_ACC); | |
594 | + | |
595 | + /* Configure the RNG Entropy Delay | |
596 | + * Performance-wise, it does not make sense to | |
597 | + * set the delay to a value that is lower | |
598 | + * than the last one that worked (i.e. the state handles | |
599 | + * were instantiated properly. Thus, instead of wasting | |
600 | + * time trying to set the values controlling the sample | |
601 | + * frequency, the function simply returns. | |
602 | + */ | |
603 | + val = __raw_readl(CAAM_RTSDCTL); | |
604 | + val &= BM_TRNG_ENT_DLY; | |
605 | + val >>= BS_TRNG_ENT_DLY; | |
606 | + if (ent_delay < val) { | |
607 | + /* Put RNG4 into run mode */ | |
608 | + clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM | RTMCTL_ACC); | |
609 | + return; | |
610 | + } | |
611 | + | |
612 | + val = (ent_delay << BS_TRNG_ENT_DLY) | samples; | |
613 | + __raw_writel(val, CAAM_RTSDCTL); | |
614 | + | |
615 | + /* min. freq. count, equal to 1/2 of the entropy sample length */ | |
616 | + __raw_writel(ent_delay >> 1, CAAM_RTFRQMIN); | |
617 | + | |
618 | + /* max. freq. count, equal to 32 times the entropy sample length */ | |
619 | + __raw_writel(ent_delay << 5, CAAM_RTFRQMAX); | |
620 | + | |
621 | + __raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC); | |
622 | + __raw_writel(poker_max, CAAM_RTPKRMAX); | |
623 | + __raw_writel(poker_range, CAAM_RTPKRRNG); | |
624 | + __raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML); | |
625 | + __raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L); | |
626 | + __raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L); | |
627 | + __raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L); | |
628 | + __raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L); | |
629 | + __raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L); | |
630 | + __raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL); | |
631 | + | |
632 | + val = __raw_readl(CAAM_RTMCTL); | |
633 | + /* | |
634 | + * Select raw sampling in both entropy shifter | |
635 | + * and statistical checker | |
636 | + */ | |
637 | + val &= ~BM_TRNG_SAMP_MODE; | |
638 | + val |= TRNG_SAMP_MODE_RAW_ES_SC; | |
639 | + /* Put RNG4 into run mode */ | |
640 | + val &= ~(RTMCTL_PGM | RTMCTL_ACC); | |
641 | +/*test with sample mode only */ | |
642 | + __raw_writel(val, CAAM_RTMCTL); | |
643 | + | |
644 | + /* Clear the ERR bit in RTMCTL if set. The TRNG error can occur when the | |
645 | + * RNG clock is not within 1/2x to 8x the system clock. | |
646 | + * This error is possible if ROM code does not initialize the system PLLs | |
647 | + * immediately after PoR. | |
648 | + */ | |
649 | + /* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */ | |
650 | +} | |
651 | + | |
670 | 652 | static int do_instantiation(void) |
671 | 653 | { |
672 | 654 | int ret = ERROR_ANY; |
... | ... | @@ -751,6 +733,79 @@ |
751 | 733 | return; |
752 | 734 | } |
753 | 735 | |
736 | +static void caam_clock_enable(void) | |
737 | +{ | |
738 | +#if defined(CONFIG_ARCH_MX6) | |
739 | + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; | |
740 | + u32 reg; | |
741 | + | |
742 | + reg = __raw_readl(&mxc_ccm->CCGR0); | |
743 | + | |
744 | + reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK | | |
745 | + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | | |
746 | + MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK); | |
747 | + | |
748 | + __raw_writel(reg, &mxc_ccm->CCGR0); | |
749 | + | |
750 | +#ifndef CONFIG_MX6UL | |
751 | + /* EMI slow clk */ | |
752 | + reg = __raw_readl(&mxc_ccm->CCGR6); | |
753 | + reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; | |
754 | + | |
755 | + __raw_writel(reg, &mxc_ccm->CCGR6); | |
756 | +#endif | |
757 | + | |
758 | +#elif defined(CONFIG_ARCH_MX7) | |
759 | + HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK); | |
760 | +#elif defined(CONFIG_ARCH_MX7ULP) | |
761 | + pcc_clock_enable(PER_CLK_CAAM, true); | |
762 | +#endif | |
763 | +} | |
764 | + | |
765 | +static int jr_reset(void) | |
766 | +{ | |
767 | + /* | |
768 | + * Function reset the Job Ring HW | |
769 | + * Reset is done in 2 steps: | |
770 | + * - Flush all pending jobs (Set RESET bit) | |
771 | + * - Reset the Job Ring (Set RESET bit second time) | |
772 | + */ | |
773 | + u16 timeout = 10000; | |
774 | + u32 reg_val; | |
775 | + | |
776 | + /* Mask interrupts to poll for reset completion status */ | |
777 | + setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK); | |
778 | + | |
779 | + /* Initiate flush (required prior to reset) */ | |
780 | + __raw_writel(JRCR_RESET, CAAM_JRCR0); | |
781 | + do { | |
782 | + reg_val = __raw_readl(CAAM_JRINTR0); | |
783 | + reg_val &= BM_JRINTR_HALT; | |
784 | + } while ((reg_val == JRINTR_HALT_ONGOING) && --timeout); | |
785 | + | |
786 | + if (!timeout || reg_val != JRINTR_HALT_DONE) { | |
787 | + printf("Failed to flush job ring\n"); | |
788 | + return ERROR_ANY; | |
789 | + } | |
790 | + | |
791 | + /* Initiate reset */ | |
792 | + timeout = 100; | |
793 | + __raw_writel(JRCR_RESET, CAAM_JRCR0); | |
794 | + do { | |
795 | + reg_val = __raw_readl(CAAM_JRCR0); | |
796 | + } while ((reg_val & JRCR_RESET) && --timeout); | |
797 | + | |
798 | + if (!timeout) { | |
799 | + printf("Failed to reset job ring\n"); | |
800 | + return ERROR_ANY; | |
801 | + } | |
802 | + | |
803 | + return 0; | |
804 | +} | |
805 | + | |
806 | +#endif /* !CONFIG_ARCH_IMX8 */ | |
807 | + | |
808 | +#ifdef CONFIG_CAAM_KB_SELF_TEST | |
754 | 809 | static void caam_hwrng_test(void) |
755 | 810 | { |
756 | 811 | ALLOC_CACHE_ALIGN_BUFFER(uint8_t, out1, 32); |
... | ... | @@ -794,4 +849,5 @@ |
794 | 849 | caam_hwrng_test(); |
795 | 850 | caam_blob_test(); |
796 | 851 | } |
852 | +#endif /* CONFIG_CAAM_KB_SELF_TEST */ |
drivers/crypto/fsl_caam_internal.h
... | ... | @@ -105,6 +105,23 @@ |
105 | 105 | #define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c) |
106 | 106 | #define CAAM_SMPO (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc) |
107 | 107 | |
108 | +/* JR0 and JR1 will be assigned to seco in imx8, so we need to | |
109 | + * use JR3 instead. | |
110 | + */ | |
111 | +#ifdef CONFIG_ARCH_IMX8 | |
112 | +#define CAAM_IRBAR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x40004) | |
113 | +#define CAAM_IRSR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x4000c) | |
114 | +#define CAAM_IRSAR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x40014) | |
115 | +#define CAAM_IRJAR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x4001c) | |
116 | +#define CAAM_ORBAR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x40024) | |
117 | +#define CAAM_ORSR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x4002c) | |
118 | +#define CAAM_ORSFR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x4003c) | |
119 | +#define CAAM_JRINTR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x4004c) | |
120 | +#define CAAM_ORJRR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x40034) | |
121 | +#define CAAM_JRCFGR3_LS (CONFIG_SYS_FSL_SEC_ADDR + 0x40054) | |
122 | +#define CAAM_JRCR3 (CONFIG_SYS_FSL_SEC_ADDR + 0x4006c) | |
123 | +#endif | |
124 | + | |
108 | 125 | #define DESC_MAX_SIZE (0x40) /* Descriptor max size */ |
109 | 126 | #define JRCFG_LS_IMSK (0x01) /* Interrupt Mask */ |
110 | 127 | #define JR_MID (0x02) /* Matches ROM configuration */ |