[PATCH 31/37] crypto: caam: Add fsl caam driver

Stefano Babic sbabic at denx.de
Thu Jul 8 10:28:58 CEST 2021


On 08.07.21 10:02, Peng Fan (OSS) wrote:
> Hi Stefano,
> 
> On 2021/4/9 2:24, Stefano Babic wrote:
>> Hi Peng,
>>
>> On 25.03.21 10:30, Peng Fan (OSS) wrote:
>>> From: Ye Li <ye.li at nxp.com>
>>>
>>> Add the fsl CAAM driver and new commands to implement DEK blob 
>>> operations,
>>> like "caam genblob" to generate encrypted blob and "caam decap" to 
>>> output
>>> orignal plain data.
>>>
>>>   The following reasons lead to instantiate the TRNG into U-Boot/SPL:
>>>
>>>   - On some i.MX platforms Linux Kernel could not instantiate RNG
>>>   - RNG could be used/needed by M4/M0 cores before Kernel stage
>>>   - Having the RNG instantiation implemented only once for
>>>     almost i.MX platforms
>>
>> Is this a CAAM driver ? But we have already drivers/crypto/fsl for 
>> CAAM. Which is the reason for it and why it is not merged with the 
>> existing driver ?
> 
> I missed this email, just check my mailbox and see this.
> My bad. I'll NXP people to merge the driver.

No problem. Patch was orthogonal, I merged the whole series but two 
patches related to the driver.

Regards,
Stefano

> 
> Thanks,
> Peng.
> 
>>
>> Best regards,
>> Stefano Babic
>>
>>>
>>> Signed-off-by: Aymen Sghaier <aymen.sghaier at nxp.com>
>>> Signed-off-by: Ye Li <ye.li at nxp.com>
>>> Signed-off-by: Peng Fan <peng.fan at nxp.com>
>>> ---
>>>   arch/arm/include/asm/arch-mx7/crm_regs.h |   8 +
>>>   cmd/Kconfig                              |   6 +
>>>   cmd/Makefile                             |   1 +
>>>   cmd/cmd_fsl_caam.c                       |  88 +++
>>>   drivers/crypto/Makefile                  |   1 +
>>>   drivers/crypto/fsl_caam.c                | 715 +++++++++++++++++++++++
>>>   drivers/crypto/fsl_caam_internal.h       | 229 ++++++++
>>>   include/fsl_caam.h                       |  24 +
>>>   8 files changed, 1072 insertions(+)
>>>   create mode 100644 cmd/cmd_fsl_caam.c
>>>   create mode 100644 drivers/crypto/fsl_caam.c
>>>   create mode 100644 drivers/crypto/fsl_caam_internal.h
>>>   create mode 100644 include/fsl_caam.h
>>>
>>> diff --git a/arch/arm/include/asm/arch-mx7/crm_regs.h 
>>> b/arch/arm/include/asm/arch-mx7/crm_regs.h
>>> index bfa68a9d2a..a000ae05d7 100644
>>> --- a/arch/arm/include/asm/arch-mx7/crm_regs.h
>>> +++ b/arch/arm/include/asm/arch-mx7/crm_regs.h
>>> @@ -1998,6 +1998,14 @@ struct mxc_ccm_anatop_reg {
>>>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT 29
>>>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR(x) 
>>> (((uint32_t)(((uint32_t)(x))<<TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT))&TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_MASK) 
>>>
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET                     12
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET)
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET                     8
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET)
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET                     4
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET)
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET                     0
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET)
>>>   #define CCM_GPR(i)        (CCM_BASE_ADDR + CCM_GPR0_OFFSET + 0x10 * 
>>> (i))
>>>   #define CCM_OBSERVE(i)        (CCM_BASE_ADDR + CCM_OBSERVE0_OFFSET 
>>> + 0x10 * (i))
>>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>>> index f73de2d75a..aeecfed974 100644
>>> --- a/cmd/Kconfig
>>> +++ b/cmd/Kconfig
>>> @@ -397,6 +397,12 @@ config CMD_SPL_WRITE_SIZE
>>>         flash used by Falcon-mode boot. See the documentation until 
>>> CMD_SPL
>>>         for detail.
>>> +config CMD_FSL_CAAM_KB
>>> +    bool "Freescale i.MX CAAM command"
>>> +    help
>>> +      Implement the "caam" command to generate DEK blob for one 
>>> block of data
>>> +      or decap the DEK blob to its original data.
>>> +
>>>   config CMD_THOR_DOWNLOAD
>>>       bool "thor - TIZEN 'thor' download"
>>>       select DFU
>>> diff --git a/cmd/Makefile b/cmd/Makefile
>>> index 567e2b79d2..d46ffd7021 100644
>>> --- a/cmd/Makefile
>>> +++ b/cmd/Makefile
>>> @@ -70,6 +70,7 @@ obj-$(CONFIG_CMD_FLASH) += flash.o
>>>   obj-$(CONFIG_CMD_FPGA) += fpga.o
>>>   obj-$(CONFIG_CMD_FPGAD) += fpgad.o
>>>   obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
>>> +obj-$(CONFIG_CMD_FSL_CAAM_KB) += cmd_fsl_caam.o
>>>   obj-$(CONFIG_CMD_FUSE) += fuse.o
>>>   obj-$(CONFIG_CMD_GETTIME) += gettime.o
>>>   obj-$(CONFIG_CMD_GPIO) += gpio.o
>>> diff --git a/cmd/cmd_fsl_caam.c b/cmd/cmd_fsl_caam.c
>>> new file mode 100644
>>> index 0000000000..d41d672320
>>> --- /dev/null
>>> +++ b/cmd/cmd_fsl_caam.c
>>> @@ -0,0 +1,88 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2012-2016 Freescale Semiconductor, Inc.
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <command.h>
>>> +#include <fsl_caam.h>
>>> +
>>> +static int do_caam(cmd_tbl_t *cmdtp, int flag, int argc, char * 
>>> const argv[])
>>> +{
>>> +    int ret, i;
>>> +
>>> +    if (argc < 2)
>>> +        return CMD_RET_USAGE;
>>> +
>>> +    if (strcmp(argv[1], "genblob") == 0) {
>>> +        if (argc != 5)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        void *data_addr;
>>> +        void *blob_addr;
>>> +        int size;
>>> +
>>> +        data_addr = (void *)simple_strtoul(argv[2], NULL, 16);
>>> +        blob_addr = (void *)simple_strtoul(argv[3], NULL, 16);
>>> +        size = simple_strtoul(argv[4], NULL, 10);
>>> +        if (size <= 48)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        caam_open();
>>> +        ret = caam_gen_blob((uint32_t)data_addr, 
>>> (uint32_t)blob_addr, (uint32_t)size);
>>> +
>>> +        if (ret != SUCCESS) {
>>> +            printf("Error during blob encap operation: 0x%x\n", ret);
>>> +            return 0;
>>> +        }
>>> +
>>> +        /* Print the generated DEK blob */
>>> +        printf("DEK blob is available at 0x%08X and equals:\n", 
>>> (unsigned int)blob_addr);
>>> +        for (i = 0; i < size; i++)
>>> +            printf("%02X ", ((uint8_t *)blob_addr)[i]);
>>> +        printf("\n\n");
>>> +
>>> +        return 1;
>>> +    } else if (strcmp(argv[1], "decap") == 0) {
>>> +        if (argc != 5)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        void *blob_addr;
>>> +        void *data_addr;
>>> +        int size;
>>> +
>>> +        blob_addr = (void *)simple_strtoul(argv[2], NULL, 16);
>>> +        data_addr = (void *)simple_strtoul(argv[3], NULL, 16);
>>> +        size      = simple_strtoul(argv[4], NULL, 10);
>>> +        if (size <= 48)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        caam_open();
>>> +        ret = caam_decap_blob((uint32_t)(data_addr), 
>>> (uint32_t)(blob_addr), (uint32_t)size);
>>> +        if (ret != SUCCESS) {
>>> +            printf("Error during blob decap operation: 0x%x\n", ret);
>>> +        } else {
>>> +            printf("Success, blob decap at SM PAGE1 original data 
>>> is:\n");
>>> +            int i = 0;
>>> +
>>> +            for (i = 0; i < size; i++) {
>>> +                printf("0x%x  ", *(unsigned char *)(data_addr + i));
>>> +                if (i % 16 == 0)
>>> +                    printf("\n");
>>> +            }
>>> +            printf("\n");
>>> +        }
>>> +
>>> +        return 1;
>>> +    }
>>> +
>>> +    return CMD_RET_USAGE;
>>> +}
>>> +
>>> +U_BOOT_CMD(
>>> +    caam, 5, 1, do_caam,
>>> +    "Freescale i.MX CAAM command",
>>> +    "caam genblob data_addr blob_addr data_size\n \
>>> +    caam decap blobaddr data_addr data_size\n \
>>> +    \n "
>>> +    );
>>> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
>>> index efbd1d3fca..6069dd5b29 100644
>>> --- a/drivers/crypto/Makefile
>>> +++ b/drivers/crypto/Makefile
>>> @@ -4,5 +4,6 @@
>>>   #     http://www.samsung.com
>>>   obj-$(CONFIG_EXYNOS_ACE_SHA)    += ace_sha.o
>>> +obj-$(CONFIG_FSL_CAAM_KB)      += fsl_caam.o
>>>   obj-y += rsa_mod_exp/
>>>   obj-y += fsl/
>>> diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c
>>> new file mode 100644
>>> index 0000000000..ccdf131635
>>> --- /dev/null
>>> +++ b/drivers/crypto/fsl_caam.c
>>> @@ -0,0 +1,715 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <malloc.h>
>>> +#include <memalign.h>
>>> +#include <asm/io.h>
>>> +#ifndef CONFIG_ARCH_MX7ULP
>>> +#include <asm/arch/crm_regs.h>
>>> +#else
>>> +#include <asm/arch/pcc.h>
>>> +#endif /* CONFIG_ARCH_MX7ULP */
>>> +#include "fsl_caam_internal.h"
>>> +#include "fsl/desc_constr.h"
>>> +#include <fsl_caam.h>
>>> +#include <cpu_func.h>
>>> +
>>> +DECLARE_GLOBAL_DATA_PTR;
>>> +
>>> +static void rng_init(void);
>>> +static void caam_clock_enable(void);
>>> +static int do_cfg_jrqueue(void);
>>> +static int do_job(u32 *desc);
>>> +static int jr_reset(void);
>>> +
>>> +/*
>>> + * Structures
>>> + */
>>> +/* Definition of input ring object */
>>> +struct inring_entry {
>>> +    u32 desc; /* Pointer to input descriptor */
>>> +};
>>> +
>>> +/* Definition of output ring object */
>>> +struct outring_entry {
>>> +    u32 desc;   /* Pointer to output descriptor */
>>> +    u32 status; /* Status of the Job Ring       */
>>> +};
>>> +
>>> +/* Main job ring data structure */
>>> +struct jr_data_st {
>>> +    struct inring_entry  *inrings;
>>> +    struct outring_entry *outrings;
>>> +    u32 status;  /* Ring buffers init status */
>>> +    u32 *desc;   /* Pointer to output descriptor */
>>> +    u32 raw_addr[DESC_MAX_SIZE * 2];
>>> +};
>>> +
>>> +/*
>>> + * Global variables
>>> + */
>>> +#if defined(CONFIG_SPL_BUILD)
>>> +static struct jr_data_st g_jrdata = {0};
>>> +#else
>>> +static struct jr_data_st g_jrdata = {0, 0, 0xFFFFFFFF};
>>> +#endif
>>> +
>>> +static u8 skeymod[] = {
>>> +    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
>>> +    0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
>>> +};
>>> +
>>> +/*
>>> + * Local functions
>>> + */
>>> +static void dump_error(void)
>>> +{
>>> +    int i;
>>> +
>>> +    debug("Dump CAAM Error\n");
>>> +    debug("MCFGR 0x%08X\n", __raw_readl(CAAM_MCFGR));
>>> +    debug("FAR  0x%08X\n", __raw_readl(CAAM_FAR));
>>> +    debug("FAMR 0x%08X\n", __raw_readl(CAAM_FAMR));
>>> +    debug("FADR 0x%08X\n", __raw_readl(CAAM_FADR));
>>> +    debug("CSTA 0x%08X\n", __raw_readl(CAAM_STA));
>>> +    debug("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
>>> +    debug("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
>>> +    debug("RDSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
>>> +
>>> +    for (i = 0; i < desc_len(g_jrdata.desc); i++)
>>> +        debug("desc[%d]: 0x%08x\n", i, g_jrdata.desc[i]);
>>> +}
>>> +
>>> +/*!
>>> + * Secure memory run command.
>>> + *
>>> + * @param   sec_mem_cmd  Secure memory command register
>>> + * @return  cmd_status  Secure memory command status register
>>> + */
>>> +u32 secmem_set_cmd_1(u32 sec_mem_cmd)
>>> +{
>>> +    u32 temp_reg;
>>> +
>>> +    __raw_writel(sec_mem_cmd, CAAM_SMCJR0);
>>> +    do {
>>> +        temp_reg = __raw_readl(CAAM_SMCSJR0);
>>> +    } while (temp_reg & CMD_COMPLETE);
>>> +
>>> +    return temp_reg;
>>> +}
>>> +
>>> +/*!
>>> + * Use CAAM to decapsulate a blob to secure memory.
>>> + * Such blob of secret key cannot be read once decrypted,
>>> + * but can still be used for enc/dec operation of user's data.
>>> + *
>>> + * @param   blob_addr  Location address of the blob.
>>> + *
>>> + * @return  SUCCESS or ERROR_XXX
>>> + */
>>> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size)
>>> +{
>>> +    u32 ret = SUCCESS;
>>> +    u32 key_sz = sizeof(skeymod);
>>> +    u32 *decap_desc = g_jrdata.desc;
>>> +
>>> +    /* prepare job descriptor */
>>> +    init_job_desc(decap_desc, 0);
>>> +    append_load(decap_desc, PTR2CAAMDMA(skeymod), key_sz,
>>> +            LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
>>> +    append_seq_in_ptr_intlen(decap_desc, blob_addr, size + 48, 0);
>>> +    append_seq_out_ptr_intlen(decap_desc, plain_text, size, 0);
>>> +    append_operation(decap_desc, OP_TYPE_DECAP_PROTOCOL | 
>>> OP_PCLID_BLOB);
>>> +
>>> +    flush_dcache_range((uintptr_t)blob_addr & ALIGN_MASK,
>>> +               ((uintptr_t)blob_addr & ALIGN_MASK)
>>> +                + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +    flush_dcache_range((uintptr_t)plain_text & ALIGN_MASK,
>>> +               (plain_text & ALIGN_MASK)
>>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +
>>> +    /* Run descriptor with result written to blob buffer */
>>> +    ret = do_job(decap_desc);
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error: blob decap job failed 0x%x\n", ret);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +/*!
>>> + * Use CAAM to generate a blob.
>>> + *
>>> + * @param   plain_data_addr  Location address of the plain data.
>>> + * @param   blob_addr  Location address of the blob.
>>> + *
>>> + * @return  SUCCESS or ERROR_XXX
>>> + */
>>> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size)
>>> +{
>>> +    u32 ret = SUCCESS;
>>> +    u32 key_sz = sizeof(skeymod);
>>> +    u32 *encap_desc = g_jrdata.desc;
>>> +    /* Buffer to hold the resulting blob */
>>> +    u8 *blob = (u8 *)CAAMDMA2PTR(blob_addr);
>>> +
>>> +    /* initialize the blob array */
>>> +    memset(blob, 0, size);
>>> +
>>> +    /* prepare job descriptor */
>>> +    init_job_desc(encap_desc, 0);
>>> +    append_load(encap_desc, PTR2CAAMDMA(skeymod), key_sz,
>>> +            LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
>>> +    append_seq_in_ptr_intlen(encap_desc, plain_data_addr, size, 0);
>>> +    append_seq_out_ptr_intlen(encap_desc, PTR2CAAMDMA(blob), size + 
>>> 48, 0);
>>> +    append_operation(encap_desc, OP_TYPE_ENCAP_PROTOCOL | 
>>> OP_PCLID_BLOB);
>>> +
>>> +    flush_dcache_range((uintptr_t)plain_data_addr & ALIGN_MASK,
>>> +               (plain_data_addr & ALIGN_MASK)
>>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +    flush_dcache_range((uintptr_t)blob & ALIGN_MASK,
>>> +               ((uintptr_t)blob & ALIGN_MASK)
>>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +
>>> +    ret = do_job(encap_desc);
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error: blob encap job failed 0x%x\n", ret);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +u32 caam_hwrng(u8 *output_ptr, u32 output_len)
>>> +{
>>> +    u32 ret = SUCCESS;
>>> +    u32 *hwrng_desc = g_jrdata.desc;
>>> +    /* Buffer to hold the resulting output*/
>>> +    u8 *output = (u8 *)output_ptr;
>>> +
>>> +    /* initialize the output array */
>>> +    memset(output, 0, output_len);
>>> +
>>> +    /* prepare job descriptor */
>>> +    init_job_desc(hwrng_desc, 0);
>>> +    append_operation(hwrng_desc, OP_ALG_ALGSEL_RNG | 
>>> OP_TYPE_CLASS1_ALG);
>>> +    append_fifo_store(hwrng_desc, PTR2CAAMDMA(output),
>>> +              output_len, FIFOST_TYPE_RNGSTORE);
>>> +
>>> +    /* flush cache */
>>> +    flush_dcache_range((uintptr_t)hwrng_desc & ALIGN_MASK,
>>> +               ((uintptr_t)hwrng_desc & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +
>>> +    ret = do_job(hwrng_desc);
>>> +
>>> +    flush_dcache_range((uintptr_t)output & ALIGN_MASK,
>>> +               ((uintptr_t)output & ALIGN_MASK)
>>> +               + ROUND(2 * output_len, ARCH_DMA_MINALIGN));
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error: RNG generate failed 0x%x\n", ret);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +/*!
>>> + * Initialize the CAAM.
>>> + *
>>> + */
>>> +void caam_open(void)
>>> +{
>>> +    u32 temp_reg;
>>> +    int ret;
>>> +
>>> +    /* switch on the clock */
>>> +#ifndef CONFIG_ARCH_IMX8
>>> +    caam_clock_enable();
>>> +#endif
>>> +
>>> +    /* reset the CAAM */
>>> +    temp_reg = __raw_readl(CAAM_MCFGR) |
>>> +            CAAM_MCFGR_DMARST | CAAM_MCFGR_SWRST;
>>> +    __raw_writel(temp_reg,  CAAM_MCFGR);
>>> +    while (__raw_readl(CAAM_MCFGR) & CAAM_MCFGR_DMARST)
>>> +        ;
>>> +
>>> +    jr_reset();
>>> +    ret = do_cfg_jrqueue();
>>> +
>>> +    if (ret != SUCCESS) {
>>> +        printf("Error CAAM JR initialization\n");
>>> +        return;
>>> +    }
>>> +
>>> +    /* Check if the RNG is already instantiated */
>>> +    temp_reg = __raw_readl(CAAM_RDSTA);
>>> +    if (temp_reg == (RDSTA_IF0 | RDSTA_IF1 | RDSTA_SKVN)) {
>>> +        printf("RNG already instantiated 0x%X\n", temp_reg);
>>> +        return;
>>> +    }
>>> +
>>> +    rng_init();
>>> +}
>>> +
>>> +static void caam_clock_enable(void)
>>> +{
>>> +#if defined(CONFIG_ARCH_MX6)
>>> +    struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
>>> +    u32 reg;
>>> +
>>> +    reg = __raw_readl(&mxc_ccm->CCGR0);
>>> +
>>> +    reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
>>> +        MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
>>> +        MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK);
>>> +
>>> +    __raw_writel(reg, &mxc_ccm->CCGR0);
>>> +
>>> +#ifndef CONFIG_MX6UL
>>> +    /* EMI slow clk */
>>> +    reg = __raw_readl(&mxc_ccm->CCGR6);
>>> +    reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
>>> +
>>> +    __raw_writel(reg, &mxc_ccm->CCGR6);
>>> +#endif
>>> +
>>> +#elif defined(CONFIG_ARCH_MX7)
>>> +    HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
>>> +#elif defined(CONFIG_ARCH_MX7ULP)
>>> +    pcc_clock_enable(PER_CLK_CAAM, true);
>>> +#endif
>>> +}
>>> +
>>> +static void kick_trng(u32 ent_delay)
>>> +{
>>> +    u32 samples  = 512; /* number of bits to generate and test */
>>> +    u32 mono_min = 195;
>>> +    u32 mono_max = 317;
>>> +    u32 mono_range  = mono_max - mono_min;
>>> +    u32 poker_min = 1031;
>>> +    u32 poker_max = 1600;
>>> +    u32 poker_range = poker_max - poker_min + 1;
>>> +    u32 retries    = 2;
>>> +    u32 lrun_max   = 32;
>>> +    s32 run_1_min   = 27;
>>> +    s32 run_1_max   = 107;
>>> +    s32 run_1_range = run_1_max - run_1_min;
>>> +    s32 run_2_min   = 7;
>>> +    s32 run_2_max   = 62;
>>> +    s32 run_2_range = run_2_max - run_2_min;
>>> +    s32 run_3_min   = 0;
>>> +    s32 run_3_max   = 39;
>>> +    s32 run_3_range = run_3_max - run_3_min;
>>> +    s32 run_4_min   = -1;
>>> +    s32 run_4_max   = 26;
>>> +    s32 run_4_range = run_4_max - run_4_min;
>>> +    s32 run_5_min   = -1;
>>> +    s32 run_5_max   = 18;
>>> +    s32 run_5_range = run_5_max - run_5_min;
>>> +    s32 run_6_min   = -1;
>>> +    s32 run_6_max   = 17;
>>> +    s32 run_6_range = run_6_max - run_6_min;
>>> +    u32 val;
>>> +
>>> +    /* Put RNG in program mode */
>>> +    setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
>>> +    /* Configure the RNG Entropy Delay
>>> +     * Performance-wise, it does not make sense to
>>> +     * set the delay to a value that is lower
>>> +     * than the last one that worked (i.e. the state handles
>>> +     * were instantiated properly. Thus, instead of wasting
>>> +     * time trying to set the values controlling the sample
>>> +     * frequency, the function simply returns.
>>> +     */
>>> +    val = __raw_readl(CAAM_RTSDCTL);
>>> +    val &= BM_TRNG_ENT_DLY;
>>> +    val >>= BS_TRNG_ENT_DLY;
>>> +    if (ent_delay < val) {
>>> +        /* Put RNG4 into run mode */
>>> +        clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
>>> +        return;
>>> +    }
>>> +
>>> +    val = (ent_delay << BS_TRNG_ENT_DLY) | samples;
>>> +    __raw_writel(val, CAAM_RTSDCTL);
>>> +
>>> +    /* min. freq. count, equal to 1/2 of the entropy sample length */
>>> +    __raw_writel(ent_delay >> 1, CAAM_RTFRQMIN);
>>> +
>>> +    /* max. freq. count, equal to 32 times the entropy sample length */
>>> +    __raw_writel(ent_delay << 5, CAAM_RTFRQMAX);
>>> +
>>> +    __raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC);
>>> +    __raw_writel(poker_max, CAAM_RTPKRMAX);
>>> +    __raw_writel(poker_range, CAAM_RTPKRRNG);
>>> +    __raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML);
>>> +    __raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L);
>>> +    __raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L);
>>> +    __raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L);
>>> +    __raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L);
>>> +    __raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L);
>>> +    __raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL);
>>> +
>>> +    val = __raw_readl(CAAM_RTMCTL);
>>> +    /*
>>> +     * Select raw sampling in both entropy shifter
>>> +     * and statistical checker
>>> +     */
>>> +    val &= ~BM_TRNG_SAMP_MODE;
>>> +    val |= TRNG_SAMP_MODE_RAW_ES_SC;
>>> +    /* Put RNG4 into run mode */
>>> +    val &= ~RTMCTL_PGM;
>>> +/*test with sample mode only */
>>> +    __raw_writel(val, CAAM_RTMCTL);
>>> +
>>> +    /* Clear the ERR bit in RTMCTL if set. The TRNG error can occur 
>>> when the
>>> +     * RNG clock is not within 1/2x to 8x the system clock.
>>> +     * This error is possible if ROM code does not initialize the 
>>> system PLLs
>>> +     * immediately after PoR.
>>> +     */
>>> +    /* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */
>>> +}
>>> +
>>> +/*
>>> + *  Descriptors to instantiate SH0, SH1, load the keys
>>> + */
>>> +static const u32 rng_inst_sh0_desc[] = {
>>> +    /* Header, don't setup the size */
>>> +    CAAM_HDR_CTYPE | CAAM_HDR_ONE | CAAM_HDR_START_INDEX(0),
>>> +    /* Operation instantiation (sh0) */
>>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(0) | 
>>> ALGO_RNG_INSTANTIATE,
>>> +};
>>> +
>>> +static const u32 rng_inst_sh1_desc[] = {
>>> +    /* wait for done - Jump to next entry */
>>> +    CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
>>> +        | CAAM_JUMP_OFFSET(1),
>>> +    /* Clear written register (write 1) */
>>> +    CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
>>> +    0x00000001,
>>> +    /* Operation instantiation (sh1) */
>>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(1)
>>> +        | ALGO_RNG_INSTANTIATE,
>>> +};
>>> +
>>> +static const u32 rng_inst_load_keys[] = {
>>> +    /* wait for done - Jump to next entry */
>>> +    CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
>>> +        | CAAM_JUMP_OFFSET(1),
>>> +    /* Clear written register (write 1) */
>>> +    CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
>>> +    0x00000001,
>>> +    /* Generate the Key */
>>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | 
>>> ALGO_RNG_GENERATE,
>>> +};
>>> +
>>> +static void do_inst_desc(u32 *desc, u32 status)
>>> +{
>>> +    u32 *pdesc = desc;
>>> +    u8  desc_len;
>>> +    bool add_sh0   = false;
>>> +    bool add_sh1   = false;
>>> +    bool load_keys = false;
>>> +
>>> +    /*
>>> +     * Modify the the descriptor to remove if necessary:
>>> +     *  - The key loading
>>> +     *  - One of the SH already instantiated
>>> +     */
>>> +    desc_len = RNG_DESC_SH0_SIZE;
>>> +    if ((status & RDSTA_IF0) != RDSTA_IF0)
>>> +        add_sh0 = true;
>>> +
>>> +    if ((status & RDSTA_IF1) != RDSTA_IF1) {
>>> +        add_sh1 = true;
>>> +        if (add_sh0)
>>> +            desc_len += RNG_DESC_SH1_SIZE;
>>> +    }
>>> +
>>> +    if ((status & RDSTA_SKVN) != RDSTA_SKVN) {
>>> +        load_keys = true;
>>> +        desc_len += RNG_DESC_KEYS_SIZE;
>>> +    }
>>> +
>>> +    /* Copy the SH0 descriptor anyway */
>>> +    memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc));
>>> +    pdesc += RNG_DESC_SH0_SIZE;
>>> +
>>> +    if (load_keys) {
>>> +        debug("RNG - Load keys\n");
>>> +        memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys));
>>> +        pdesc += RNG_DESC_KEYS_SIZE;
>>> +    }
>>> +
>>> +    if (add_sh1) {
>>> +        if (add_sh0) {
>>> +            debug("RNG - Instantiation of SH0 and SH1\n");
>>> +            /* Add the sh1 descriptor */
>>> +            memcpy(pdesc, rng_inst_sh1_desc,
>>> +                   sizeof(rng_inst_sh1_desc));
>>> +        } else {
>>> +            debug("RNG - Instantiation of SH1 only\n");
>>> +            /* Modify the SH0 descriptor to instantiate only SH1 */
>>> +            desc[1] &= ~BM_ALGO_RNG_SH;
>>> +            desc[1] |= ALGO_RNG_SH(1);
>>> +        }
>>> +    }
>>> +
>>> +    /* Setup the descriptor size */
>>> +    desc[0] &= ~(0x3F);
>>> +    desc[0] |= CAAM_HDR_DESCLEN(desc_len);
>>> +}
>>> +
>>> +static int jr_reset(void)
>>> +{
>>> +    /*
>>> +     * Function reset the Job Ring HW
>>> +     * Reset is done in 2 steps:
>>> +     *  - Flush all pending jobs (Set RESET bit)
>>> +     *  - Reset the Job Ring (Set RESET bit second time)
>>> +     */
>>> +    u16 timeout = 10000;
>>> +    u32 reg_val;
>>> +
>>> +    /* Mask interrupts to poll for reset completion status */
>>> +    setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK);
>>> +
>>> +    /* Initiate flush (required prior to reset) */
>>> +    __raw_writel(JRCR_RESET, CAAM_JRCR0);
>>> +    do {
>>> +        reg_val = __raw_readl(CAAM_JRINTR0);
>>> +        reg_val &= BM_JRINTR_HALT;
>>> +    } while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);
>>> +
>>> +    if (!timeout  || reg_val != JRINTR_HALT_DONE) {
>>> +        printf("Failed to flush job ring\n");
>>> +        return ERROR_ANY;
>>> +    }
>>> +
>>> +    /* Initiate reset */
>>> +    timeout = 100;
>>> +    __raw_writel(JRCR_RESET, CAAM_JRCR0);
>>> +    do {
>>> +        reg_val = __raw_readl(CAAM_JRCR0);
>>> +    } while ((reg_val & JRCR_RESET) && --timeout);
>>> +
>>> +    if (!timeout) {
>>> +        printf("Failed to reset job ring\n");
>>> +        return ERROR_ANY;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int do_job(u32 *desc)
>>> +{
>>> +    int ret;
>>> +    phys_addr_t p_desc = virt_to_phys(desc);
>>> +
>>> +    if (__raw_readl(CAAM_IRSAR0) == 0)
>>> +        return ERROR_ANY;
>>> +    g_jrdata.inrings[0].desc = p_desc;
>>> +
>>> +    flush_dcache_range((uintptr_t)g_jrdata.inrings & ALIGN_MASK,
>>> +               ((uintptr_t)g_jrdata.inrings & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +    flush_dcache_range((uintptr_t)desc & ALIGN_MASK,
>>> +               ((uintptr_t)desc & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +
>>> +    /* Inform HW that a new JR is available */
>>> +    __raw_writel(1, CAAM_IRJAR0);
>>> +    while (__raw_readl(CAAM_ORSFR0) == 0)
>>> +        ;
>>> +
>>> +    flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK,
>>> +               ((uintptr_t)g_jrdata.outrings & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +
>>> +    if (PTR2CAAMDMA(desc) == g_jrdata.outrings[0].desc) {
>>> +        ret = g_jrdata.outrings[0].status;
>>> +    } else {
>>> +        dump_error();
>>> +        ret = ERROR_ANY;
>>> +    }
>>> +
>>> +    /* Acknowledge interrupt */
>>> +    setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
>>> +
>>> +    /* Remove the JR from the output list even if no JR caller found */
>>> +    __raw_writel(1, CAAM_ORJRR0);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int do_cfg_jrqueue(void)
>>> +{
>>> +    u32 value = 0;
>>> +    phys_addr_t ip_base;
>>> +    phys_addr_t op_base;
>>> +
>>> +    /* check if already configured after relocation */
>>> +    if (g_jrdata.status == RING_RELOC_INIT)
>>> +        return 0;
>>> +
>>> +    /*
>>> +     * jr configuration needs to be updated once, after relocation 
>>> to ensure
>>> +     * using the right buffers.
>>> +     * When buffers are updated after relocation the flag 
>>> RING_RELOC_INIT
>>> +     * is used to prevent extra updates
>>> +     */
>>> +    if (gd->flags & GD_FLG_RELOC) {
>>> +        g_jrdata.inrings  = (struct inring_entry *)
>>> +                    memalign(ARCH_DMA_MINALIGN,
>>> +                         ARCH_DMA_MINALIGN);
>>> +        g_jrdata.outrings = (struct outring_entry *)
>>> +                    memalign(ARCH_DMA_MINALIGN,
>>> +                         ARCH_DMA_MINALIGN);
>>> +        g_jrdata.desc = (u32 *)
>>> +                memalign(ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
>>> +        g_jrdata.status = RING_RELOC_INIT;
>>> +    } else {
>>> +        u32 align_idx = 0;
>>> +
>>> +        /* Ensure 64bits buffers addresses alignment */
>>> +        if ((uintptr_t)g_jrdata.raw_addr & 0x7)
>>> +            align_idx = 1;
>>> +        g_jrdata.inrings  = (struct inring_entry *)
>>> +                    (&g_jrdata.raw_addr[align_idx]);
>>> +        g_jrdata.outrings = (struct outring_entry *)
>>> +                    (&g_jrdata.raw_addr[align_idx + 2]);
>>> +        g_jrdata.desc = (u32 *)(&g_jrdata.raw_addr[align_idx + 4]);
>>> +        g_jrdata.status = RING_EARLY_INIT;
>>> +    }
>>> +
>>> +    if (!g_jrdata.inrings || !g_jrdata.outrings)
>>> +        return ERROR_ANY;
>>> +
>>> +    /* Configure the HW Job Rings */
>>> +    ip_base = virt_to_phys((void *)g_jrdata.inrings);
>>> +    op_base = virt_to_phys((void *)g_jrdata.outrings);
>>> +    __raw_writel(ip_base, CAAM_IRBAR0);
>>> +    __raw_writel(1, CAAM_IRSR0);
>>> +
>>> +    __raw_writel(op_base, CAAM_ORBAR0);
>>> +    __raw_writel(1, CAAM_ORSR0);
>>> +
>>> +    setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
>>> +
>>> +    /*
>>> +     * Configure interrupts but disable it:
>>> +     * Optimization to generate an interrupt either when there are
>>> +     * half of the job done or when there is a job done and
>>> +     * 10 clock cycles elapse without new job complete
>>> +     */
>>> +    value = 10 << BS_JRCFGR_LS_ICTT;
>>> +    value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT;
>>> +    value |= BM_JRCFGR_LS_ICEN;
>>> +    value |= BM_JRCFGR_LS_IMSK;
>>> +    __raw_writel(value, CAAM_JRCFGR0_LS);
>>> +
>>> +    /* Enable deco watchdog */
>>> +    setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static void do_clear_rng_error(void)
>>> +{
>>> +    u32 val;
>>> +
>>> +    val = __raw_readl(CAAM_RTMCTL);
>>> +
>>> +    if (val & (RTMCTL_ERR | RTMCTL_FCT_FAIL)) {
>>> +        setbits_le32(CAAM_RTMCTL, RTMCTL_ERR);
>>> +    val = __raw_readl(CAAM_RTMCTL);
>>> +    }
>>> +}
>>> +
>>> +static int do_instantiation(void)
>>> +{
>>> +    int ret = ERROR_ANY;
>>> +    u32 cha_vid_ls;
>>> +    u32 ent_delay;
>>> +    u32 status;
>>> +
>>> +    if (!g_jrdata.desc) {
>>> +        printf("%d: CAAM Descriptor allocation error\n", __LINE__);
>>> +        return ERROR_ANY;
>>> +    }
>>> +
>>> +    cha_vid_ls = __raw_readl(CAAM_CHAVID_LS);
>>> +
>>> +    /*
>>> +     * If SEC has RNG version >= 4 and RNG state handle has not been
>>> +     * already instantiated, do RNG instantiation
>>> +     */
>>> +    if (((cha_vid_ls & BM_CHAVID_LS_RNGVID) >> BS_CHAVID_LS_RNGVID) 
>>> < 4) {
>>> +        printf("%d: RNG already instantiated\n", __LINE__);
>>> +        return 0;
>>> +    }
>>> +
>>> +    ent_delay = TRNG_SDCTL_ENT_DLY_MIN;
>>> +
>>> +    do {
>>> +        /* Read the CAAM RNG status */
>>> +        status = __raw_readl(CAAM_RDSTA);
>>> +
>>> +        if ((status & RDSTA_IF0) != RDSTA_IF0) {
>>> +            /* Configure the RNG entropy delay */
>>> +            kick_trng(ent_delay);
>>> +            ent_delay += 400;
>>> +        }
>>> +
>>> +        do_clear_rng_error();
>>> +
>>> +        if ((status & (RDSTA_IF0 | RDSTA_IF1)) !=
>>> +                (RDSTA_IF0 | RDSTA_IF1)) {
>>> +            /* Prepare the instantiation descriptor */
>>> +            do_inst_desc(g_jrdata.desc, status);
>>> +
>>> +            /* Run Job */
>>> +            ret = do_job(g_jrdata.desc);
>>> +
>>> +            if (ret == ERROR_ANY) {
>>> +                /* CAAM JR failure ends here */
>>> +                printf("RNG Instantiation error\n");
>>> +                goto end_instantation;
>>> +            }
>>> +        } else {
>>> +            ret = SUCCESS;
>>> +            printf("RNG instantiation done (%d)\n", ent_delay);
>>> +            goto end_instantation;
>>> +        }
>>> +    } while (ent_delay < TRNG_SDCTL_ENT_DLY_MAX);
>>> +
>>> +    printf("RNG Instantation Failure - Entropy delay (%d)\n", 
>>> ent_delay);
>>> +    ret = ERROR_ANY;
>>> +
>>> +end_instantation:
>>> +    return ret;
>>> +}
>>> +
>>> +static void rng_init(void)
>>> +{
>>> +    int  ret;
>>> +
>>> +    ret = jr_reset();
>>> +    if (ret != SUCCESS) {
>>> +        printf("Error CAAM JR reset\n");
>>> +        return;
>>> +    }
>>> +
>>> +    ret = do_instantiation();
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error do_instantiation\n");
>>> +
>>> +    jr_reset();
>>> +
>>> +    return;
>>> +}
>>> +
>>> diff --git a/drivers/crypto/fsl_caam_internal.h 
>>> b/drivers/crypto/fsl_caam_internal.h
>>> new file mode 100644
>>> index 0000000000..837562d3c4
>>> --- /dev/null
>>> +++ b/drivers/crypto/fsl_caam_internal.h
>>> @@ -0,0 +1,229 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>>> + * Copyright 2018 NXP
>>> + */
>>> +
>>> +#ifndef __CAAM_INTERNAL_H__
>>> +#define __CAAM_INTERNAL_H__
>>> +
>>> +/* 4kbyte pages */
>>> +#define CAAM_SEC_RAM_START_ADDR CAAM_ARB_BASE_ADDR
>>> +
>>> +#define SEC_MEM_PAGE0       CAAM_SEC_RAM_START_ADDR
>>> +#define SEC_MEM_PAGE1       (CAAM_SEC_RAM_START_ADDR + 0x1000)
>>> +#define SEC_MEM_PAGE2       (CAAM_SEC_RAM_START_ADDR + 0x2000)
>>> +#define SEC_MEM_PAGE3       (CAAM_SEC_RAM_START_ADDR + 0x3000)
>>> +
>>> +/* Configuration and special key registers */
>>> +#define CAAM_MCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0004)
>>> +#define CAAM_SCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x000c)
>>> +#define CAAM_JR0MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0010)
>>> +#define CAAM_JR1MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0018)
>>> +#define CAAM_DECORR         (CONFIG_SYS_FSL_SEC_ADDR + 0x009c)
>>> +#define CAAM_DECO0MID       (CONFIG_SYS_FSL_SEC_ADDR + 0x00a0)
>>> +#define CAAM_DAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0120)
>>> +#define CAAM_DRR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0124)
>>> +#define CAAM_JDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0400)
>>> +#define CAAM_TDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0420)
>>> +#define CAAM_TDSKR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0440)
>>> +#define CAAM_SKNR           (CONFIG_SYS_FSL_SEC_ADDR + 0x04e0)
>>> +#define CAAM_SMSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4)
>>> +#define CAAM_STA            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4)
>>> +#define CAAM_SMPO_0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
>>> +#define CAAM_CHAVID_LS      (CONFIG_SYS_FSL_SEC_ADDR + 0x0FEC)
>>> +#define CAAM_FAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC0)
>>> +#define CAAM_FAMR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC8)
>>> +#define CAAM_FADR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FCC)
>>> +
>>> +/* RNG registers */
>>> +#define CAAM_RTMCTL         (CONFIG_SYS_FSL_SEC_ADDR + 0x0600)
>>> +#define CAAM_RTSCMISC       (CONFIG_SYS_FSL_SEC_ADDR + 0x0604)
>>> +#define CAAM_RTPKRRNG       (CONFIG_SYS_FSL_SEC_ADDR + 0x0608)
>>> +#define CAAM_RTPKRMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x060C)
>>> +#define CAAM_RTSDCTL        (CONFIG_SYS_FSL_SEC_ADDR + 0x0610)
>>> +#define CAAM_RTFRQMIN       (CONFIG_SYS_FSL_SEC_ADDR + 0x0618)
>>> +#define CAAM_RTFRQMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x061C)
>>> +#define CAAM_RTSCML         (CONFIG_SYS_FSL_SEC_ADDR + 0x0620)
>>> +#define CAAM_RTSCR1L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0624)
>>> +#define CAAM_RTSCR2L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0628)
>>> +#define CAAM_RTSCR3L        (CONFIG_SYS_FSL_SEC_ADDR + 0x062C)
>>> +#define CAAM_RTSCR4L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0630)
>>> +#define CAAM_RTSCR5L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0634)
>>> +#define CAAM_RTSCR6PL       (CONFIG_SYS_FSL_SEC_ADDR + 0x0638)
>>> +#define CAAM_RTSTATUS       (CONFIG_SYS_FSL_SEC_ADDR + 0x063C)
>>> +#define CAAM_RDSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x06C0)
>>> +
>>> +/* Job Ring 0 registers */
>>> +#define CAAM_IRBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1004)
>>> +#define CAAM_IRSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x100c)
>>> +#define CAAM_IRSAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1014)
>>> +#define CAAM_IRJAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x101c)
>>> +#define CAAM_ORBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1024)
>>> +#define CAAM_ORSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x102c)
>>> +#define CAAM_ORJRR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1034)
>>> +#define CAAM_ORSFR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x103c)
>>> +#define CAAM_JRSTAR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x1044)
>>> +#define CAAM_JRINTR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x104c)
>>> +#define CAAM_JRCFGR0_MS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1050)
>>> +#define CAAM_JRCFGR0_LS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1054)
>>> +#define CAAM_IRRIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x105c)
>>> +#define CAAM_ORWIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1064)
>>> +#define CAAM_JRCR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x106c)
>>> +#define CAAM_SMCJR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x10f4)
>>> +#define CAAM_SMCSJR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x10fc)
>>> +#define CAAM_SMAPJR0(y)     (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y * 16)
>>> +#define CAAM_SMAG2JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y * 16)
>>> +#define CAAM_SMAG1JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y * 16)
>>> +#define CAAM_SMAPJR0_PRTN1  (CONFIG_SYS_FSL_SEC_ADDR + 0x1114)
>>> +#define CAAM_SMAG2JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1118)
>>> +#define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c)
>>> +#define CAAM_SMPO           (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc)
>>> +
>>> +#define DESC_MAX_SIZE       (0x40)        /* Descriptor max size */
>>> +#define JRCFG_LS_IMSK       (0x01)        /* Interrupt Mask */
>>> +#define JR_MID              (0x02)        /* Matches ROM 
>>> configuration */
>>> +#define KS_G1               BIT(JR_MID)   /* CAAM only */
>>> +#define PERM                (0x0000B008)  /* Clear on release, lock 
>>> SMAP,
>>> +                       * lock SMAG and group 1 Blob
>>> +                       */
>>> +
>>> +#define CMD_PAGE_ALLOC      (0x1)
>>> +#define CMD_PAGE_DEALLOC    (0x2)
>>> +#define CMD_PART_DEALLOC    (0x3)
>>> +#define CMD_INQUIRY         (0x5)
>>> +#define PAGE(x)             ((x) << 16)
>>> +#define PARTITION(x)        ((x) << 8)
>>> +
>>> +#define SMCSJR_AERR         (3 << 12)
>>> +#define SMCSJR_CERR         (3 << 14)
>>> +#define CMD_COMPLETE        (3 << 14)
>>> +
>>> +#define SMCSJR_PO           (3 << 6)
>>> +#define PAGE_AVAILABLE      (0)
>>> +#define PAGE_OWNED          (3 << 6)
>>> +
>>> +#define PARTITION_OWNER(x)  (0x3 << ((x) * 2))
>>> +
>>> +#define CAAM_BUSY_MASK      (0x00000001) /* BUSY from status reg */
>>> +#define CAAM_IDLE_MASK      (0x00000002) /* IDLE from status reg */
>>> +#define CAAM_MCFGR_SWRST    BIT(31)      /* CAAM SW reset */
>>> +#define CAAM_MCFGR_DMARST   BIT(28)      /* CAAM DMA reset */
>>> +
>>> +#define JOB_RING_ENTRIES    (1)
>>> +#define JOB_RING_STS        (0xF << 28)
>>> +
>>> +/** OSC_DIV in RNG trim fuses */
>>> +#define RNG_TRIM_OSC_DIV    (0)
>>> +/** ENT_DLY multiplier in RNG trim fuses */
>>> +#define TRNG_SDCTL_ENT_DLY_MIN (3200)
>>> +#define TRNG_SDCTL_ENT_DLY_MAX (4800)
>>> +
>>> +#define RTMCTL_PGM       BIT(16)
>>> +#define RTMCTL_ERR       BIT(12)
>>> +#define RTMCTL_RST       BIT(6)
>>> +#define RDSTA_IF0        (1)
>>> +#define RDSTA_IF1        (2)
>>> +#define RDSTA_SKVN       BIT(30)
>>> +#define JRCR_RESET       (1)
>>> +#define RTMCTL_FCT_FAIL  BIT(8)
>>> +
>>> +#define BS_TRNG_ENT_DLY     (16)
>>> +#define BM_TRNG_ENT_DLY     (0xffff << BS_TRNG_ENT_DLY)
>>> +#define BM_TRNG_SAMP_MODE   (3)
>>> +#define TRNG_SAMP_MODE_RAW_ES_SC (1)
>>> +#define BS_JRINTR_HALT      (2)
>>> +#define BM_JRINTR_HALT      (0x3 << BS_JRINTR_HALT)
>>> +#define JRINTR_HALT_ONGOING (0x1 << BS_JRINTR_HALT)
>>> +#define JRINTR_HALT_DONE    (0x2 << BS_JRINTR_HALT)
>>> +#define JRINTR_JRI          (0x1)
>>> +#define BS_JRCFGR_LS_ICTT   (16)
>>> +#define BM_JRCFGR_LS_ICTT   (0xFFFF << BS_JRCFGR_LS_ICTT)
>>> +#define BS_JRCFGR_LS_ICDCT  (8)
>>> +#define BM_JRCFGR_LS_ICDCT  (0xFF << BS_JRCFGR_LS_ICDCT)
>>> +#define BS_JRCFGR_LS_ICEN   (1)
>>> +#define BM_JRCFGR_LS_ICEN   (0x1 << BS_JRCFGR_LS_ICEN)
>>> +#define BS_JRCFGR_LS_IMSK   (0)
>>> +#define BM_JRCFGR_LS_IMSK   (0x1 << BS_JRCFGR_LS_IMSK)
>>> +#define BS_CHAVID_LS_RNGVID (16)
>>> +#define BM_CHAVID_LS_RNGVID (0xF << BS_CHAVID_LS_RNGVID)
>>> +#define BS_MCFGR_WDE        (30)
>>> +#define BM_MCFGR_WDE        (0x1 << BS_MCFGR_WDE)
>>> +
>>> +typedef enum {
>>> +    PAGE_0,
>>> +    PAGE_1,
>>> +    PAGE_2,
>>> +    PAGE_3,
>>> +} page_num_e;
>>> +
>>> +typedef enum {
>>> +    PARTITION_0,
>>> +    PARTITION_1,
>>> +    PARTITION_2,
>>> +    PARTITION_3,
>>> +    PARTITION_4,
>>> +    PARTITION_5,
>>> +    PARTITION_6,
>>> +    PARTITION_7,
>>> +} partition_num_e;
>>> +
>>> +/*
>>> + * Local defines
>>> + */
>>> +/* arm v7 need 64 align */
>>> +#define ALIGN_MASK     ~(ARCH_DMA_MINALIGN - 1)
>>> +/* caam dma and pointer conversion for arm and arm64 architectures */
>>> +#ifdef CONFIG_IMX_CONFIG
>>> +  #define PTR2CAAMDMA(x)  (u32)((uintptr_t)(x) & 0xffffffff)
>>> +  #define CAAMDMA2PTR(x)  (uintptr_t)((x) & 0xffffffff)
>>> +#else
>>> +  #define PTR2CAAMDMA(x)  (uintptr_t)(x)
>>> +  #define CAAMDMA2PTR(x)  (uintptr_t)(x)
>>> +#endif
>>> +#define RING_EARLY_INIT   (0x01)
>>> +#define RING_RELOC_INIT   (0x02)
>>> +
>>> +#define CAAM_HDR_CTYPE            (0x16u << 27)
>>> +#define CAAM_HDR_ONE              BIT(23)
>>> +#define CAAM_HDR_START_INDEX(x)   (((x) & 0x3F) << 16)
>>> +#define CAAM_HDR_DESCLEN(x)       ((x) & 0x3F)
>>> +#define CAAM_PROTOP_CTYPE         (0x10u << 27)
>>> +
>>> +/* State Handle */
>>> +#define BS_ALGO_RNG_SH            (4)
>>> +#define BM_ALGO_RNG_SH            (0x3 << BS_ALGO_RNG_SH)
>>> +#define ALGO_RNG_SH(id)           (((id) << BS_ALGO_RNG_SH) & 
>>> BM_ALGO_RNG_SH)
>>> +
>>> +/* Secure Key */
>>> +#define BS_ALGO_RNG_SK            (12)
>>> +#define BM_ALGO_RNG_SK            BIT(BS_ALGO_RNG_SK)
>>> +
>>> +/* State */
>>> +#define BS_ALGO_RNG_AS            (2)
>>> +#define BM_ALGO_RNG_AS            (0x3 << BS_ALGO_RNG_AS)
>>> +#define ALGO_RNG_GENERATE         (0x0 << BS_ALGO_RNG_AS)
>>> +#define ALGO_RNG_INSTANTIATE      BIT(BS_ALGO_RNG_AS)
>>> +
>>> +#define CAAM_C1_RNG               ((0x50 << 16) | (2 << 24))
>>> +
>>> +#define BS_JUMP_LOCAL_OFFSET      (0)
>>> +#define BM_JUMP_LOCAL_OFFSET      (0xFF << BS_JUMP_LOCAL_OFFSET)
>>> +
>>> +#define CAAM_C1_JUMP              ((0x14u << 27) | (1 << 25))
>>> +#define CAAM_JUMP_LOCAL           (0 << 20)
>>> +#define CAAM_JUMP_TST_ALL_COND_TRUE (0 << 16)
>>> +#define CAAM_JUMP_OFFSET(off)     (((off) << BS_JUMP_LOCAL_OFFSET) \
>>> +                & BM_JUMP_LOCAL_OFFSET)
>>> +
>>> +#define CAAM_C0_LOAD_IMM          ((0x2 << 27) | (1 << 23))
>>> +#define CAAM_DST_CLEAR_WRITTEN    (0x8 << 16)
>>> +
>>> +#define RNG_DESC_SH0_SIZE   (ARRAY_SIZE(rng_inst_sh0_desc))
>>> +#define RNG_DESC_SH1_SIZE   (ARRAY_SIZE(rng_inst_sh1_desc))
>>> +#define RNG_DESC_KEYS_SIZE  (ARRAY_SIZE(rng_inst_load_keys))
>>> +#define RNG_DESC_MAX_SIZE   (RNG_DESC_SH0_SIZE + \
>>> +            RNG_DESC_SH1_SIZE + \
>>> +            RNG_DESC_KEYS_SIZE)
>>> +
>>> +#endif /* __CAAM_INTERNAL_H__ */
>>> diff --git a/include/fsl_caam.h b/include/fsl_caam.h
>>> new file mode 100644
>>> index 0000000000..c4345ae2b6
>>> --- /dev/null
>>> +++ b/include/fsl_caam.h
>>> @@ -0,0 +1,24 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>>> + * Copyright 2018 NXP
>>> + */
>>> +
>>> +#ifndef __CAAM_H__
>>> +#define    __CAAM_H__
>>> +
>>> +#if !defined(SUCCESS)
>>> +#define SUCCESS (0)
>>> +#endif
>>> +
>>> +#define ERROR_ANY           (-1)
>>> +#define ERROR_IN_PAGE_ALLOC (1)
>>> +
>>> +void caam_open(void);
>>> +
>>> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size);
>>> +
>>> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size);
>>> +u32 caam_hwrng(uint8_t *output_ptr, u32 output_len);
>>> +
>>> +#endif /* __CAAM_H__ */
>>>
>>
>>


-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================


More information about the U-Boot mailing list