[PATCH 31/37] crypto: caam: Add fsl caam driver
Peng Fan (OSS)
peng.fan at oss.nxp.com
Thu Jul 8 10:02:08 CEST 2021
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.
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__ */
>>
>
>
More information about the U-Boot
mailing list