mbox series

[00/37] imx: hab/caam new feature and update

Message ID 20210325093036.3270101-1-peng.fan@oss.nxp.com
Headers show
Series imx: hab/caam new feature and update | expand

Message

Peng Fan (OSS) March 25, 2021, 9:29 a.m. UTC
From: Peng <peng.fan@nxp.com>


This patchset is to upstream NXP downstream caam, hab features
One more patch is to update maintainer for imx8mn_evk board.

Aymen Sghaier (6):
  crypto: caam: Add CAAM support to i.MX8M platforms
  crypto: caam: Fix build warnings pointer casting
  crypto: Add blob command support for i.MX8M platforms
  crypto: caam: Fix pointer size to 32bit for i.MX8M
  crypto: caam: Add secure memory vid 3 support
  crypto: caam: RNG4 TRNG errata

Breno Lima (13):
  imx: imx7 Support for Manufacturing Protection
  imx: Avoid hardcoded output ring size register offset (ORSR)
  imx: Ensure CAAM clock is enabled prior getting out_jr_size
  imx: Avoid hardcoded Job Ring Max size
  imx: hab: Enable hab.c to authenticate additional images in open
    configuration
  imx: hab: Check if IVT header is HABv4
  mx7ulp: hab: Add hab_status command for HABv4 M4 boot
  imx: hab: Fix build warnings in 32-bit targets
  crypto: fsl: blob: Flush dcache range for destination address
  mx6dq: hab: Fix chip version in hab.h code
  cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency
  cmd: blob: Instantiate RNG before running CMD_BLOB
  fsl_mfgprot: Fix typo in sign_mppubk()

Clement Faure (2):
  imx8m: Add DEK blob encapsulation for imx8m
  imx8: Add DEK blob encapsulation

Clement Le Marquis (1):
  imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR
    register to 0x3

Franck LENORMAND (3):
  crypto: caam: change JR running loop
  caam: enable support for iMX7ULP
  imx7ulp: Enable support for cmd blob

Peng (1):
  imx8mn: evk: update MAINTAINERS

Peng Fan (2):
  imx8m: add regs used by CAAM
  imx: HAB: Update hab codes to support ARM64 and i.MX8M

Utkarsh Gupta (2):
  imx: HAB: Validate IVT before authenticating image
  imx: hab: Display All HAB events via hab_status command

Ye Li (7):
  imx: hab: Add function to authenticate kernel image
  hab: Change calling to ROM API failsafe
  imx: HAB: Add support for iMX8MM
  iMX8M: Add support to enable CONFIG_IMX_HAB
  imx: cmd_dek: Enable DEK only for chips supporting CAAM
  crypto: caam: Add fsl caam driver
  crypto: fsl: refactor for 32 bit version CAAM support on ARM64

 arch/arm/Kconfig                             |   6 +
 arch/arm/dts/imx8mm-evk-u-boot.dtsi          |   7 +
 arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi     |   6 +
 arch/arm/dts/imx8mp-evk-u-boot.dtsi          |   6 +
 arch/arm/include/asm/arch-imx/cpu.h          |   1 +
 arch/arm/include/asm/arch-imx8/image.h       |  11 +
 arch/arm/include/asm/arch-imx8m/clock.h      |   1 +
 arch/arm/include/asm/arch-imx8m/imx-regs.h   |  10 +
 arch/arm/include/asm/arch-mx7/crm_regs.h     |   8 +
 arch/arm/include/asm/arch-mx7ulp/imx-regs.h  |  12 +
 arch/arm/include/asm/mach-imx/hab.h          |  37 +-
 arch/arm/mach-imx/Kconfig                    |  44 +-
 arch/arm/mach-imx/Makefile                   |   3 +
 arch/arm/mach-imx/cmd_dek.c                  | 262 ++++++-
 arch/arm/mach-imx/cmd_mfgprot.c              | 150 ++++
 arch/arm/mach-imx/hab.c                      | 417 +++++++++--
 arch/arm/mach-imx/imx8/Kconfig               |   1 +
 arch/arm/mach-imx/imx8m/Kconfig              |   1 +
 arch/arm/mach-imx/imx8m/clock_imx8mm.c       |   8 +
 arch/arm/mach-imx/imx8m/clock_imx8mq.c       |   7 +
 arch/arm/mach-imx/mx7ulp/Kconfig             |   1 +
 arch/arm/mach-imx/priblob.c                  |  33 +
 board/freescale/imx8mn_evk/MAINTAINERS       |   3 +-
 cmd/Kconfig                                  |   8 +
 cmd/Makefile                                 |   1 +
 cmd/blob.c                                   |  16 +
 cmd/cmd_fsl_caam.c                           |  88 +++
 doc/imx/habv4/guides/mx6_mx7_secure_boot.txt |  25 +
 drivers/crypto/Makefile                      |   1 +
 drivers/crypto/fsl/Kconfig                   |   6 +
 drivers/crypto/fsl/Makefile                  |   4 +-
 drivers/crypto/fsl/desc.h                    |  49 +-
 drivers/crypto/fsl/desc_constr.h             |  28 +-
 drivers/crypto/fsl/fsl_blob.c                |   6 +
 drivers/crypto/fsl/fsl_hash.c                |   6 +-
 drivers/crypto/fsl/fsl_mfgprot.c             | 160 +++++
 drivers/crypto/fsl/jobdesc.c                 |  16 +-
 drivers/crypto/fsl/jr.c                      |  53 +-
 drivers/crypto/fsl/jr.h                      |  11 +-
 drivers/crypto/fsl/type.h                    |  16 +
 drivers/crypto/fsl_caam.c                    | 720 +++++++++++++++++++
 drivers/crypto/fsl_caam_internal.h           | 230 ++++++
 include/fsl_caam.h                           |  24 +
 include/fsl_sec.h                            |  54 +-
 44 files changed, 2388 insertions(+), 169 deletions(-)
 create mode 100644 arch/arm/mach-imx/cmd_mfgprot.c
 create mode 100644 arch/arm/mach-imx/priblob.c
 create mode 100644 cmd/cmd_fsl_caam.c
 create mode 100644 drivers/crypto/fsl/fsl_mfgprot.c
 create mode 100644 drivers/crypto/fsl/type.h
 create mode 100644 drivers/crypto/fsl_caam.c
 create mode 100644 drivers/crypto/fsl_caam_internal.h
 create mode 100644 include/fsl_caam.h

-- 
2.25.1

Comments

Horia Geanta March 31, 2021, 12:32 p.m. UTC | #1
On 3/25/2021 11:32 AM, Peng Fan (OSS) wrote:
> From: Peng <peng.fan@nxp.com>

> 

> This patchset is to upstream NXP downstream caam, hab features


I don't think adding yet another caam driver (drivers/crypto/fsl_caam.c)
is a good idea.
Instead existing driver (drivers/crypto/fsl/*) should be extended / modified.

> One more patch is to update maintainer for imx8mn_evk board.

> 

> Aymen Sghaier (6):

>   crypto: caam: Add CAAM support to i.MX8M platforms

>   crypto: caam: Fix build warnings pointer casting

>   crypto: Add blob command support for i.MX8M platforms

>   crypto: caam: Fix pointer size to 32bit for i.MX8M

>   crypto: caam: Add secure memory vid 3 support

>   crypto: caam: RNG4 TRNG errata

> 

> Breno Lima (13):

>   imx: imx7 Support for Manufacturing Protection

>   imx: Avoid hardcoded output ring size register offset (ORSR)

>   imx: Ensure CAAM clock is enabled prior getting out_jr_size

>   imx: Avoid hardcoded Job Ring Max size

>   imx: hab: Enable hab.c to authenticate additional images in open

>     configuration

>   imx: hab: Check if IVT header is HABv4

>   mx7ulp: hab: Add hab_status command for HABv4 M4 boot

>   imx: hab: Fix build warnings in 32-bit targets

>   crypto: fsl: blob: Flush dcache range for destination address

>   mx6dq: hab: Fix chip version in hab.h code

>   cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency

>   cmd: blob: Instantiate RNG before running CMD_BLOB

>   fsl_mfgprot: Fix typo in sign_mppubk()

> 

> Clement Faure (2):

>   imx8m: Add DEK blob encapsulation for imx8m

>   imx8: Add DEK blob encapsulation

> 

> Clement Le Marquis (1):

>   imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR

>     register to 0x3

> 

> Franck LENORMAND (3):

>   crypto: caam: change JR running loop

>   caam: enable support for iMX7ULP

>   imx7ulp: Enable support for cmd blob

> 

> Peng (1):

>   imx8mn: evk: update MAINTAINERS

> 

> Peng Fan (2):

>   imx8m: add regs used by CAAM

>   imx: HAB: Update hab codes to support ARM64 and i.MX8M

> 

> Utkarsh Gupta (2):

>   imx: HAB: Validate IVT before authenticating image

>   imx: hab: Display All HAB events via hab_status command

> 

> Ye Li (7):

>   imx: hab: Add function to authenticate kernel image

>   hab: Change calling to ROM API failsafe

>   imx: HAB: Add support for iMX8MM

>   iMX8M: Add support to enable CONFIG_IMX_HAB

>   imx: cmd_dek: Enable DEK only for chips supporting CAAM

>   crypto: caam: Add fsl caam driver

>   crypto: fsl: refactor for 32 bit version CAAM support on ARM64

> 

There are several patches fixing newly added code.
Internal development history is of little value, fixes should be squashed.

Horia
Stefano Babic April 8, 2021, 6:24 p.m. UTC | #2
Hi Peng,

On 25.03.21 10:30, Peng Fan (OSS) wrote:
> From: Ye Li <ye.li@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 ?

Best regards,
Stefano Babic

> 

> Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>

> Signed-off-by: Ye Li <ye.li@nxp.com>

> Signed-off-by: Peng Fan <peng.fan@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__ */

>
Peng Fan (OSS) July 8, 2021, 8:02 a.m. UTC | #3
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@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@nxp.com>

>> Signed-off-by: Ye Li <ye.li@nxp.com>

>> Signed-off-by: Peng Fan <peng.fan@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__ */

>>

> 

>
Stefano Babic July 8, 2021, 8:28 a.m. UTC | #4
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@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@nxp.com>

>>> Signed-off-by: Ye Li <ye.li@nxp.com>

>>> Signed-off-by: Peng Fan <peng.fan@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@denx.de
=====================================================================