Commit 4c3f9727 authored by Gilad Ben-Yossef's avatar Gilad Ben-Yossef Committed by Herbert Xu

crypto: ccree - introduce CryptoCell driver

Introduce basic low level Arm TrustZone CryptoCell HW support.
This first patch doesn't actually register any Crypto API
transformations, these will follow up in the next patch.

This first revision supports the CC 712 REE component.
Signed-off-by: default avatarGilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent e294ca1c
...@@ -730,4 +730,31 @@ config CRYPTO_DEV_ARTPEC6 ...@@ -730,4 +730,31 @@ config CRYPTO_DEV_ARTPEC6
To compile this driver as a module, choose M here. To compile this driver as a module, choose M here.
config CRYPTO_DEV_CCREE
tristate "Support for ARM TrustZone CryptoCell family of security processors"
depends on CRYPTO && CRYPTO_HW && OF && HAS_DMA
default n
select CRYPTO_HASH
select CRYPTO_BLKCIPHER
select CRYPTO_DES
select CRYPTO_AEAD
select CRYPTO_AUTHENC
select CRYPTO_SHA1
select CRYPTO_MD5
select CRYPTO_SHA256
select CRYPTO_SHA512
select CRYPTO_HMAC
select CRYPTO_AES
select CRYPTO_CBC
select CRYPTO_ECB
select CRYPTO_CTR
select CRYPTO_XTS
help
Say 'Y' to enable a driver for the Arm TrustZone CryptoCell
family of processors. Currently only the CryptoCell 712 REE
is supported.
Choose this if you wish to use hardware acceleration of
cryptographic operations on the system REE.
If unsure say Y.
endif # CRYPTO_HW endif # CRYPTO_HW
...@@ -6,6 +6,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_ECC) += atmel-ecc.o ...@@ -6,6 +6,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_ECC) += atmel-ecc.o
obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o
obj-$(CONFIG_CRYPTO_DEV_CAVIUM_ZIP) += cavium/ obj-$(CONFIG_CRYPTO_DEV_CAVIUM_ZIP) += cavium/
obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/ obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chelsio/ obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chelsio/
obj-$(CONFIG_CRYPTO_DEV_CPT) += cavium/cpt/ obj-$(CONFIG_CRYPTO_DEV_CPT) += cavium/cpt/
obj-$(CONFIG_CRYPTO_DEV_NITROX) += cavium/nitrox/ obj-$(CONFIG_CRYPTO_DEV_NITROX) += cavium/nitrox/
......
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o
ccree-y := cc_driver.o cc_buffer_mgr.o cc_request_mgr.o cc_ivgen.o cc_sram_mgr.o
ccree-$(CONFIG_DEBUG_FS) += cc_debugfs.o
ccree-$(CONFIG_PM) += cc_pm.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
/* \file cc_buffer_mgr.h
* Buffer Manager
*/
#ifndef __CC_BUFFER_MGR_H__
#define __CC_BUFFER_MGR_H__
#include <crypto/algapi.h>
#include "cc_driver.h"
enum cc_req_dma_buf_type {
CC_DMA_BUF_NULL = 0,
CC_DMA_BUF_DLLI,
CC_DMA_BUF_MLLI
};
enum cc_sg_cpy_direct {
CC_SG_TO_BUF = 0,
CC_SG_FROM_BUF = 1
};
struct cc_mlli {
cc_sram_addr_t sram_addr;
unsigned int nents; //sg nents
unsigned int mlli_nents; //mlli nents might be different than the above
};
struct mlli_params {
struct dma_pool *curr_pool;
u8 *mlli_virt_addr;
dma_addr_t mlli_dma_addr;
u32 mlli_len;
};
int cc_buffer_mgr_init(struct cc_drvdata *drvdata);
int cc_buffer_mgr_fini(struct cc_drvdata *drvdata);
int cc_map_hash_request_final(struct cc_drvdata *drvdata, void *ctx,
struct scatterlist *src, unsigned int nbytes,
bool do_update, gfp_t flags);
int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx,
struct scatterlist *src, unsigned int nbytes,
unsigned int block_size, gfp_t flags);
void cc_unmap_hash_request(struct device *dev, void *ctx,
struct scatterlist *src, bool do_revert);
void cc_copy_sg_portion(struct device *dev, u8 *dest, struct scatterlist *sg,
u32 to_skip, u32 end, enum cc_sg_cpy_direct direct);
void cc_zero_sgl(struct scatterlist *sgl, u32 data_len);
#endif /*__BUFFER_MGR_H__*/
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef _CC_CRYPTO_CTX_H_
#define _CC_CRYPTO_CTX_H_
#include <linux/types.h>
/* context size */
#ifndef CC_CTX_SIZE_LOG2
#if (CC_DEV_SHA_MAX > 256)
#define CC_CTX_SIZE_LOG2 8
#else
#define CC_CTX_SIZE_LOG2 7
#endif
#endif
#define CC_CTX_SIZE BIT(CC_CTX_SIZE_LOG2)
#define CC_DRV_CTX_SIZE_WORDS (CC_CTX_SIZE >> 2)
#define CC_DRV_DES_IV_SIZE 8
#define CC_DRV_DES_BLOCK_SIZE 8
#define CC_DRV_DES_ONE_KEY_SIZE 8
#define CC_DRV_DES_DOUBLE_KEY_SIZE 16
#define CC_DRV_DES_TRIPLE_KEY_SIZE 24
#define CC_DRV_DES_KEY_SIZE_MAX CC_DRV_DES_TRIPLE_KEY_SIZE
#define CC_AES_IV_SIZE 16
#define CC_AES_IV_SIZE_WORDS (CC_AES_IV_SIZE >> 2)
#define CC_AES_BLOCK_SIZE 16
#define CC_AES_BLOCK_SIZE_WORDS 4
#define CC_AES_128_BIT_KEY_SIZE 16
#define CC_AES_128_BIT_KEY_SIZE_WORDS (CC_AES_128_BIT_KEY_SIZE >> 2)
#define CC_AES_192_BIT_KEY_SIZE 24
#define CC_AES_192_BIT_KEY_SIZE_WORDS (CC_AES_192_BIT_KEY_SIZE >> 2)
#define CC_AES_256_BIT_KEY_SIZE 32
#define CC_AES_256_BIT_KEY_SIZE_WORDS (CC_AES_256_BIT_KEY_SIZE >> 2)
#define CC_AES_KEY_SIZE_MAX CC_AES_256_BIT_KEY_SIZE
#define CC_AES_KEY_SIZE_WORDS_MAX (CC_AES_KEY_SIZE_MAX >> 2)
#define CC_MD5_DIGEST_SIZE 16
#define CC_SHA1_DIGEST_SIZE 20
#define CC_SHA224_DIGEST_SIZE 28
#define CC_SHA256_DIGEST_SIZE 32
#define CC_SHA256_DIGEST_SIZE_IN_WORDS 8
#define CC_SHA384_DIGEST_SIZE 48
#define CC_SHA512_DIGEST_SIZE 64
#define CC_SHA1_BLOCK_SIZE 64
#define CC_SHA1_BLOCK_SIZE_IN_WORDS 16
#define CC_MD5_BLOCK_SIZE 64
#define CC_MD5_BLOCK_SIZE_IN_WORDS 16
#define CC_SHA224_BLOCK_SIZE 64
#define CC_SHA256_BLOCK_SIZE 64
#define CC_SHA256_BLOCK_SIZE_IN_WORDS 16
#define CC_SHA1_224_256_BLOCK_SIZE 64
#define CC_SHA384_BLOCK_SIZE 128
#define CC_SHA512_BLOCK_SIZE 128
#if (CC_DEV_SHA_MAX > 256)
#define CC_DIGEST_SIZE_MAX CC_SHA512_DIGEST_SIZE
#define CC_HASH_BLOCK_SIZE_MAX CC_SHA512_BLOCK_SIZE /*1024b*/
#else /* Only up to SHA256 */
#define CC_DIGEST_SIZE_MAX CC_SHA256_DIGEST_SIZE
#define CC_HASH_BLOCK_SIZE_MAX CC_SHA256_BLOCK_SIZE /*512b*/
#endif
#define CC_HMAC_BLOCK_SIZE_MAX CC_HASH_BLOCK_SIZE_MAX
#define CC_DRV_ALG_MAX_BLOCK_SIZE CC_HASH_BLOCK_SIZE_MAX
enum drv_engine_type {
DRV_ENGINE_NULL = 0,
DRV_ENGINE_AES = 1,
DRV_ENGINE_DES = 2,
DRV_ENGINE_HASH = 3,
DRV_ENGINE_RC4 = 4,
DRV_ENGINE_DOUT = 5,
DRV_ENGINE_RESERVE32B = S32_MAX,
};
enum drv_crypto_alg {
DRV_CRYPTO_ALG_NULL = -1,
DRV_CRYPTO_ALG_AES = 0,
DRV_CRYPTO_ALG_DES = 1,
DRV_CRYPTO_ALG_HASH = 2,
DRV_CRYPTO_ALG_C2 = 3,
DRV_CRYPTO_ALG_HMAC = 4,
DRV_CRYPTO_ALG_AEAD = 5,
DRV_CRYPTO_ALG_BYPASS = 6,
DRV_CRYPTO_ALG_NUM = 7,
DRV_CRYPTO_ALG_RESERVE32B = S32_MAX
};
enum drv_crypto_direction {
DRV_CRYPTO_DIRECTION_NULL = -1,
DRV_CRYPTO_DIRECTION_ENCRYPT = 0,
DRV_CRYPTO_DIRECTION_DECRYPT = 1,
DRV_CRYPTO_DIRECTION_DECRYPT_ENCRYPT = 3,
DRV_CRYPTO_DIRECTION_RESERVE32B = S32_MAX
};
enum drv_cipher_mode {
DRV_CIPHER_NULL_MODE = -1,
DRV_CIPHER_ECB = 0,
DRV_CIPHER_CBC = 1,
DRV_CIPHER_CTR = 2,
DRV_CIPHER_CBC_MAC = 3,
DRV_CIPHER_XTS = 4,
DRV_CIPHER_XCBC_MAC = 5,
DRV_CIPHER_OFB = 6,
DRV_CIPHER_CMAC = 7,
DRV_CIPHER_CCM = 8,
DRV_CIPHER_CBC_CTS = 11,
DRV_CIPHER_GCTR = 12,
DRV_CIPHER_ESSIV = 13,
DRV_CIPHER_BITLOCKER = 14,
DRV_CIPHER_RESERVE32B = S32_MAX
};
enum drv_hash_mode {
DRV_HASH_NULL = -1,
DRV_HASH_SHA1 = 0,
DRV_HASH_SHA256 = 1,
DRV_HASH_SHA224 = 2,
DRV_HASH_SHA512 = 3,
DRV_HASH_SHA384 = 4,
DRV_HASH_MD5 = 5,
DRV_HASH_CBC_MAC = 6,
DRV_HASH_XCBC_MAC = 7,
DRV_HASH_CMAC = 8,
DRV_HASH_MODE_NUM = 9,
DRV_HASH_RESERVE32B = S32_MAX
};
enum drv_hash_hw_mode {
DRV_HASH_HW_MD5 = 0,
DRV_HASH_HW_SHA1 = 1,
DRV_HASH_HW_SHA256 = 2,
DRV_HASH_HW_SHA224 = 10,
DRV_HASH_HW_SHA512 = 4,
DRV_HASH_HW_SHA384 = 12,
DRV_HASH_HW_GHASH = 6,
DRV_HASH_HW_RESERVE32B = S32_MAX
};
/* drv_crypto_key_type[1:0] is mapped to cipher_do[1:0] */
/* drv_crypto_key_type[2] is mapped to cipher_config2 */
enum drv_crypto_key_type {
DRV_NULL_KEY = -1,
DRV_USER_KEY = 0, /* 0x000 */
DRV_ROOT_KEY = 1, /* 0x001 */
DRV_PROVISIONING_KEY = 2, /* 0x010 */
DRV_SESSION_KEY = 3, /* 0x011 */
DRV_APPLET_KEY = 4, /* NA */
DRV_PLATFORM_KEY = 5, /* 0x101 */
DRV_CUSTOMER_KEY = 6, /* 0x110 */
DRV_END_OF_KEYS = S32_MAX,
};
enum drv_crypto_padding_type {
DRV_PADDING_NONE = 0,
DRV_PADDING_PKCS7 = 1,
DRV_PADDING_RESERVE32B = S32_MAX
};
#endif /* _CC_CRYPTO_CTX_H_ */
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/stringify.h>
#include "cc_driver.h"
#include "cc_crypto_ctx.h"
#include "cc_debugfs.h"
struct cc_debugfs_ctx {
struct dentry *dir;
};
#define CC_DEBUG_REG(_X) { \
.name = __stringify(_X),\
.offset = CC_REG(_X) \
}
/*
* This is a global var for the dentry of the
* debugfs ccree/ dir. It is not tied down to
* a specific instance of ccree, hence it is
* global.
*/
static struct dentry *cc_debugfs_dir;
static struct debugfs_reg32 debug_regs[] = {
CC_DEBUG_REG(HOST_SIGNATURE),
CC_DEBUG_REG(HOST_IRR),
CC_DEBUG_REG(HOST_POWER_DOWN_EN),
CC_DEBUG_REG(AXIM_MON_ERR),
CC_DEBUG_REG(DSCRPTR_QUEUE_CONTENT),
CC_DEBUG_REG(HOST_IMR),
CC_DEBUG_REG(AXIM_CFG),
CC_DEBUG_REG(AXIM_CACHE_PARAMS),
CC_DEBUG_REG(HOST_VERSION),
CC_DEBUG_REG(GPR_HOST),
CC_DEBUG_REG(AXIM_MON_COMP),
};
int __init cc_debugfs_global_init(void)
{
cc_debugfs_dir = debugfs_create_dir("ccree", NULL);
return !cc_debugfs_dir;
}
void __exit cc_debugfs_global_fini(void)
{
debugfs_remove(cc_debugfs_dir);
}
int cc_debugfs_init(struct cc_drvdata *drvdata)
{
struct device *dev = drvdata_to_dev(drvdata);
struct cc_debugfs_ctx *ctx;
struct debugfs_regset32 *regset;
struct dentry *file;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
if (!regset)
return -ENOMEM;
regset->regs = debug_regs;
regset->nregs = ARRAY_SIZE(debug_regs);
regset->base = drvdata->cc_base;
ctx->dir = debugfs_create_dir(drvdata->plat_dev->name, cc_debugfs_dir);
if (!ctx->dir)
return -ENFILE;
file = debugfs_create_regset32("regs", 0400, ctx->dir, regset);
if (!file) {
debugfs_remove(ctx->dir);
return -ENFILE;
}
file = debugfs_create_bool("coherent", 0400, ctx->dir,
&drvdata->coherent);
if (!file) {
debugfs_remove_recursive(ctx->dir);
return -ENFILE;
}
drvdata->debugfs = ctx;
return 0;
}
void cc_debugfs_fini(struct cc_drvdata *drvdata)
{
struct cc_debugfs_ctx *ctx = (struct cc_debugfs_ctx *)drvdata->debugfs;
debugfs_remove_recursive(ctx->dir);
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef __CC_DEBUGFS_H__
#define __CC_DEBUGFS_H__
#ifdef CONFIG_DEBUG_FS
int cc_debugfs_global_init(void);
void cc_debugfs_global_fini(void);
int cc_debugfs_init(struct cc_drvdata *drvdata);
void cc_debugfs_fini(struct cc_drvdata *drvdata);
#else
static inline int cc_debugfs_global_init(void)
{
return 0;
}
static inline void cc_debugfs_global_fini(void) {}
static inline int cc_debugfs_init(struct cc_drvdata *drvdata)
{
return 0;
}
static inline void cc_debugfs_fini(struct cc_drvdata *drvdata) {}
#endif
#endif /*__CC_SYSFS_H__*/
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
/* \file cc_driver.h
* ARM CryptoCell Linux Crypto Driver
*/
#ifndef __CC_DRIVER_H__
#define __CC_DRIVER_H__
#ifdef COMP_IN_WQ
#include <linux/workqueue.h>
#else
#include <linux/interrupt.h>
#endif
#include <linux/dma-mapping.h>
#include <crypto/algapi.h>
#include <crypto/aes.h>
#include <crypto/sha.h>
#include <crypto/aead.h>
#include <crypto/authenc.h>
#include <crypto/hash.h>
#include <crypto/skcipher.h>
#include <linux/version.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
/* Registers definitions from shared/hw/ree_include */
#include "cc_host_regs.h"
#define CC_DEV_SHA_MAX 512
#include "cc_crypto_ctx.h"
#include "cc_hw_queue_defs.h"
#include "cc_sram_mgr.h"
extern bool cc_dump_desc;
extern bool cc_dump_bytes;
#define DRV_MODULE_VERSION "3.0"
#define CC_DEV_NAME_STR "ccree"
#define CC_COHERENT_CACHE_PARAMS 0xEEE
/* Maximum DMA mask supported by IP */
#define DMA_BIT_MASK_LEN 48
#define CC_DEV_SIGNATURE 0xDCC71200UL
#define CC_AXI_IRQ_MASK ((1 << CC_AXIM_CFG_BRESPMASK_BIT_SHIFT) | \
(1 << CC_AXIM_CFG_RRESPMASK_BIT_SHIFT) | \
(1 << CC_AXIM_CFG_INFLTMASK_BIT_SHIFT) | \
(1 << CC_AXIM_CFG_COMPMASK_BIT_SHIFT))
#define CC_AXI_ERR_IRQ_MASK BIT(CC_HOST_IRR_AXI_ERR_INT_BIT_SHIFT)
#define CC_COMP_IRQ_MASK BIT(CC_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT)
#define AXIM_MON_COMP_VALUE GENMASK(CC_AXIM_MON_COMP_VALUE_BIT_SIZE + \
CC_AXIM_MON_COMP_VALUE_BIT_SHIFT, \
CC_AXIM_MON_COMP_VALUE_BIT_SHIFT)
/* Register name mangling macro */
#define CC_REG(reg_name) CC_ ## reg_name ## _REG_OFFSET
/* TEE FIPS status interrupt */
#define CC_GPR0_IRQ_MASK BIT(CC_HOST_IRR_GPR0_BIT_SHIFT)
#define CC_CRA_PRIO 400
#define MIN_HW_QUEUE_SIZE 50 /* Minimum size required for proper function */
#define MAX_REQUEST_QUEUE_SIZE 4096
#define MAX_MLLI_BUFF_SIZE 2080
#define MAX_ICV_NENTS_SUPPORTED 2
/* Definitions for HW descriptors DIN/DOUT fields */
#define NS_BIT 1
#define AXI_ID 0
/* AXI_ID is not actually the AXI ID of the transaction but the value of AXI_ID
* field in the HW descriptor. The DMA engine +8 that value.
*/
#define CC_MAX_IVGEN_DMA_ADDRESSES 3
struct cc_crypto_req {
void (*user_cb)(struct device *dev, void *req, int err);
void *user_arg;
dma_addr_t ivgen_dma_addr[CC_MAX_IVGEN_DMA_ADDRESSES];
/* For the first 'ivgen_dma_addr_len' addresses of this array,
* generated IV would be placed in it by send_request().
* Same generated IV for all addresses!
*/
/* Amount of 'ivgen_dma_addr' elements to be filled. */
unsigned int ivgen_dma_addr_len;
/* The generated IV size required, 8/16 B allowed. */
unsigned int ivgen_size;
struct completion seq_compl; /* request completion */
};
/**
* struct cc_drvdata - driver private data context
* @cc_base: virt address of the CC registers
* @irq: device IRQ number
* @irq_mask: Interrupt mask shadow (1 for masked interrupts)
* @fw_ver: SeP loaded firmware version
*/
struct cc_drvdata {
void __iomem *cc_base;
int irq;
u32 irq_mask;
u32 fw_ver;
struct completion hw_queue_avail; /* wait for HW queue availability */
struct platform_device *plat_dev;
cc_sram_addr_t mlli_sram_addr;
void *buff_mgr_handle;
void *request_mgr_handle;
void *ivgen_handle;
void *sram_mgr_handle;
void *debugfs;
struct clk *clk;
bool coherent;
};
struct cc_crypto_alg {
struct list_head entry;
int cipher_mode;
int flow_mode; /* Note: currently, refers to the cipher mode only. */
int auth_mode;
struct cc_drvdata *drvdata;
struct crypto_alg crypto_alg;
};
struct cc_alg_template {
char name[CRYPTO_MAX_ALG_NAME];
char driver_name[CRYPTO_MAX_ALG_NAME];
unsigned int blocksize;
u32 type;
union {
struct skcipher_alg skcipher;
struct aead_alg aead;
} template_u;
int cipher_mode;
int flow_mode; /* Note: currently, refers to the cipher mode only. */
int auth_mode;
struct cc_drvdata *drvdata;
};
struct async_gen_req_ctx {
dma_addr_t iv_dma_addr;
enum drv_crypto_direction op_type;
};
static inline struct device *drvdata_to_dev(struct cc_drvdata *drvdata)
{
return &drvdata->plat_dev->dev;
}
void __dump_byte_array(const char *name, const u8 *buf, size_t len);
static inline void dump_byte_array(const char *name, const u8 *the_array,
size_t size)
{
if (cc_dump_bytes)
__dump_byte_array(name, the_array, size);
}
int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe);
void fini_cc_regs(struct cc_drvdata *drvdata);
int cc_clk_on(struct cc_drvdata *drvdata);
void cc_clk_off(struct cc_drvdata *drvdata);
static inline void cc_iowrite(struct cc_drvdata *drvdata, u32 reg, u32 val)
{
iowrite32(val, (drvdata->cc_base + reg));
}
static inline u32 cc_ioread(struct cc_drvdata *drvdata, u32 reg)
{
return ioread32(drvdata->cc_base + reg);
}
static inline gfp_t cc_gfp_flags(struct crypto_async_request *req)
{
return (req->flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
GFP_KERNEL : GFP_ATOMIC;
}
#endif /*__CC_DRIVER_H__*/
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef __CC_HOST_H__
#define __CC_HOST_H__
// --------------------------------------
// BLOCK: HOST_P
// --------------------------------------
#define CC_HOST_IRR_REG_OFFSET 0xA00UL
#define CC_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SHIFT 0x2UL
#define CC_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SIZE 0x1UL
#define CC_HOST_IRR_AXI_ERR_INT_BIT_SHIFT 0x8UL
#define CC_HOST_IRR_AXI_ERR_INT_BIT_SIZE 0x1UL
#define CC_HOST_IRR_GPR0_BIT_SHIFT 0xBUL
#define CC_HOST_IRR_GPR0_BIT_SIZE 0x1UL
#define CC_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SHIFT 0x13UL
#define CC_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SIZE 0x1UL
#define CC_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT 0x17UL
#define CC_HOST_IRR_AXIM_COMP_INT_BIT_SIZE 0x1UL
#define CC_HOST_IMR_REG_OFFSET 0xA04UL
#define CC_HOST_IMR_NOT_USED_MASK_BIT_SHIFT 0x1UL
#define CC_HOST_IMR_NOT_USED_MASK_BIT_SIZE 0x1UL
#define CC_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SHIFT 0x2UL
#define CC_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SIZE 0x1UL
#define CC_HOST_IMR_AXI_ERR_MASK_BIT_SHIFT 0x8UL
#define CC_HOST_IMR_AXI_ERR_MASK_BIT_SIZE 0x1UL
#define CC_HOST_IMR_GPR0_BIT_SHIFT 0xBUL
#define CC_HOST_IMR_GPR0_BIT_SIZE 0x1UL
#define CC_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SHIFT 0x13UL
#define CC_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SIZE 0x1UL
#define CC_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SHIFT 0x17UL
#define CC_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SIZE 0x1UL
#define CC_HOST_ICR_REG_OFFSET 0xA08UL
#define CC_HOST_ICR_DSCRPTR_COMPLETION_BIT_SHIFT 0x2UL
#define CC_HOST_ICR_DSCRPTR_COMPLETION_BIT_SIZE 0x1UL
#define CC_HOST_ICR_AXI_ERR_CLEAR_BIT_SHIFT 0x8UL
#define CC_HOST_ICR_AXI_ERR_CLEAR_BIT_SIZE 0x1UL
#define CC_HOST_ICR_GPR_INT_CLEAR_BIT_SHIFT 0xBUL
#define CC_HOST_ICR_GPR_INT_CLEAR_BIT_SIZE 0x1UL
#define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SHIFT 0x13UL
#define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SIZE 0x1UL
#define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SHIFT 0x17UL
#define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SIZE 0x1UL
#define CC_HOST_SIGNATURE_REG_OFFSET 0xA24UL
#define CC_HOST_SIGNATURE_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_SIGNATURE_VALUE_BIT_SIZE 0x20UL
#define CC_HOST_BOOT_REG_OFFSET 0xA28UL
#define CC_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SHIFT 0x0UL
#define CC_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SHIFT 0x1UL
#define CC_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SHIFT 0x2UL
#define CC_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SHIFT 0x3UL
#define CC_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SHIFT 0x5UL
#define CC_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SHIFT 0x6UL
#define CC_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SIZE 0x3UL
#define CC_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SHIFT 0x9UL
#define CC_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SHIFT 0xAUL
#define CC_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SHIFT 0xBUL
#define CC_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SHIFT 0xCUL
#define CC_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SHIFT 0xDUL
#define CC_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SHIFT 0xEUL
#define CC_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SHIFT 0xFUL
#define CC_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SHIFT 0x10UL
#define CC_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SHIFT 0x11UL
#define CC_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SHIFT 0x12UL
#define CC_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SHIFT 0x13UL
#define CC_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SHIFT 0x14UL
#define CC_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SHIFT 0x15UL
#define CC_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SHIFT 0x16UL
#define CC_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SHIFT 0x17UL
#define CC_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SHIFT 0x18UL
#define CC_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SHIFT 0x19UL
#define CC_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SHIFT 0x1AUL
#define CC_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SHIFT 0x1BUL
#define CC_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SHIFT 0x1CUL
#define CC_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SHIFT 0x1DUL
#define CC_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SHIFT 0x1EUL
#define CC_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SIZE 0x1UL
#define CC_HOST_VERSION_REG_OFFSET 0xA40UL
#define CC_HOST_VERSION_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_VERSION_VALUE_BIT_SIZE 0x20UL
#define CC_HOST_KFDE0_VALID_REG_OFFSET 0xA60UL
#define CC_HOST_KFDE0_VALID_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_KFDE0_VALID_VALUE_BIT_SIZE 0x1UL
#define CC_HOST_KFDE1_VALID_REG_OFFSET 0xA64UL
#define CC_HOST_KFDE1_VALID_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_KFDE1_VALID_VALUE_BIT_SIZE 0x1UL
#define CC_HOST_KFDE2_VALID_REG_OFFSET 0xA68UL
#define CC_HOST_KFDE2_VALID_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_KFDE2_VALID_VALUE_BIT_SIZE 0x1UL
#define CC_HOST_KFDE3_VALID_REG_OFFSET 0xA6CUL
#define CC_HOST_KFDE3_VALID_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_KFDE3_VALID_VALUE_BIT_SIZE 0x1UL
#define CC_HOST_GPR0_REG_OFFSET 0xA70UL
#define CC_HOST_GPR0_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_GPR0_VALUE_BIT_SIZE 0x20UL
#define CC_GPR_HOST_REG_OFFSET 0xA74UL
#define CC_GPR_HOST_VALUE_BIT_SHIFT 0x0UL
#define CC_GPR_HOST_VALUE_BIT_SIZE 0x20UL
#define CC_HOST_POWER_DOWN_EN_REG_OFFSET 0xA78UL
#define CC_HOST_POWER_DOWN_EN_VALUE_BIT_SHIFT 0x0UL
#define CC_HOST_POWER_DOWN_EN_VALUE_BIT_SIZE 0x1UL
// --------------------------------------
// BLOCK: HOST_SRAM
// --------------------------------------
#define CC_SRAM_DATA_REG_OFFSET 0xF00UL
#define CC_SRAM_DATA_VALUE_BIT_SHIFT 0x0UL
#define CC_SRAM_DATA_VALUE_BIT_SIZE 0x20UL
#define CC_SRAM_ADDR_REG_OFFSET 0xF04UL
#define CC_SRAM_ADDR_VALUE_BIT_SHIFT 0x0UL
#define CC_SRAM_ADDR_VALUE_BIT_SIZE 0xFUL
#define CC_SRAM_DATA_READY_REG_OFFSET 0xF08UL
#define CC_SRAM_DATA_READY_VALUE_BIT_SHIFT 0x0UL
#define CC_SRAM_DATA_READY_VALUE_BIT_SIZE 0x1UL
#endif //__CC_HOST_H__
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#include <crypto/ctr.h>
#include "cc_driver.h"
#include "cc_ivgen.h"
#include "cc_request_mgr.h"
#include "cc_sram_mgr.h"
#include "cc_buffer_mgr.h"
/* The max. size of pool *MUST* be <= SRAM total size */
#define CC_IVPOOL_SIZE 1024
/* The first 32B fraction of pool are dedicated to the
* next encryption "key" & "IV" for pool regeneration
*/
#define CC_IVPOOL_META_SIZE (CC_AES_IV_SIZE + AES_KEYSIZE_128)
#define CC_IVPOOL_GEN_SEQ_LEN 4
/**
* struct cc_ivgen_ctx -IV pool generation context
* @pool: the start address of the iv-pool resides in internal RAM
* @ctr_key_dma: address of pool's encryption key material in internal RAM
* @ctr_iv_dma: address of pool's counter iv in internal RAM
* @next_iv_ofs: the offset to the next available IV in pool
* @pool_meta: virt. address of the initial enc. key/IV
* @pool_meta_dma: phys. address of the initial enc. key/IV
*/
struct cc_ivgen_ctx {
cc_sram_addr_t pool;
cc_sram_addr_t ctr_key;
cc_sram_addr_t ctr_iv;
u32 next_iv_ofs;
u8 *pool_meta;
dma_addr_t pool_meta_dma;
};
/*!
* Generates CC_IVPOOL_SIZE of random bytes by
* encrypting 0's using AES128-CTR.
*
* \param ivgen iv-pool context
* \param iv_seq IN/OUT array to the descriptors sequence
* \param iv_seq_len IN/OUT pointer to the sequence length
*/
static int cc_gen_iv_pool(struct cc_ivgen_ctx *ivgen_ctx,
struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len)
{
unsigned int idx = *iv_seq_len;
if ((*iv_seq_len + CC_IVPOOL_GEN_SEQ_LEN) > CC_IVPOOL_SEQ_LEN) {
/* The sequence will be longer than allowed */
return -EINVAL;
}
/* Setup key */
hw_desc_init(&iv_seq[idx]);
set_din_sram(&iv_seq[idx], ivgen_ctx->ctr_key, AES_KEYSIZE_128);
set_setup_mode(&iv_seq[idx], SETUP_LOAD_KEY0);
set_cipher_config0(&iv_seq[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
set_flow_mode(&iv_seq[idx], S_DIN_to_AES);
set_key_size_aes(&iv_seq[idx], CC_AES_128_BIT_KEY_SIZE);
set_cipher_mode(&iv_seq[idx], DRV_CIPHER_CTR);
idx++;
/* Setup cipher state */
hw_desc_init(&iv_seq[idx]);
set_din_sram(&iv_seq[idx], ivgen_ctx->ctr_iv, CC_AES_IV_SIZE);
set_cipher_config0(&iv_seq[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
set_flow_mode(&iv_seq[idx], S_DIN_to_AES);
set_setup_mode(&iv_seq[idx], SETUP_LOAD_STATE1);
set_key_size_aes(&iv_seq[idx], CC_AES_128_BIT_KEY_SIZE);
set_cipher_mode(&iv_seq[idx], DRV_CIPHER_CTR);
idx++;
/* Perform dummy encrypt to skip first block */
hw_desc_init(&iv_seq[idx]);
set_din_const(&iv_seq[idx], 0, CC_AES_IV_SIZE);
set_dout_sram(&iv_seq[idx], ivgen_ctx->pool, CC_AES_IV_SIZE);
set_flow_mode(&iv_seq[idx], DIN_AES_DOUT);
idx++;
/* Generate IV pool */
hw_desc_init(&iv_seq[idx]);
set_din_const(&iv_seq[idx], 0, CC_IVPOOL_SIZE);
set_dout_sram(&iv_seq[idx], ivgen_ctx->pool, CC_IVPOOL_SIZE);
set_flow_mode(&iv_seq[idx], DIN_AES_DOUT);
idx++;
*iv_seq_len = idx; /* Update sequence length */
/* queue ordering assures pool readiness */
ivgen_ctx->next_iv_ofs = CC_IVPOOL_META_SIZE;
return 0;
}
/*!
* Generates the initial pool in SRAM.
* This function should be invoked when resuming driver.
*
* \param drvdata
*
* \return int Zero for success, negative value otherwise.
*/
int cc_init_iv_sram(struct cc_drvdata *drvdata)
{
struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
struct cc_hw_desc iv_seq[CC_IVPOOL_SEQ_LEN];
unsigned int iv_seq_len = 0;
int rc;
/* Generate initial enc. key/iv */
get_random_bytes(ivgen_ctx->pool_meta, CC_IVPOOL_META_SIZE);
/* The first 32B reserved for the enc. Key/IV */
ivgen_ctx->ctr_key = ivgen_ctx->pool;
ivgen_ctx->ctr_iv = ivgen_ctx->pool + AES_KEYSIZE_128;
/* Copy initial enc. key and IV to SRAM at a single descriptor */
hw_desc_init(&iv_seq[iv_seq_len]);
set_din_type(&iv_seq[iv_seq_len], DMA_DLLI, ivgen_ctx->pool_meta_dma,
CC_IVPOOL_META_SIZE, NS_BIT);
set_dout_sram(&iv_seq[iv_seq_len], ivgen_ctx->pool,
CC_IVPOOL_META_SIZE);
set_flow_mode(&iv_seq[iv_seq_len], BYPASS);
iv_seq_len++;
/* Generate initial pool */
rc = cc_gen_iv_pool(ivgen_ctx, iv_seq, &iv_seq_len);
if (rc)
return rc;
/* Fire-and-forget */
return send_request_init(drvdata, iv_seq, iv_seq_len);
}
/*!
* Free iv-pool and ivgen context.
*
* \param drvdata
*/
void cc_ivgen_fini(struct cc_drvdata *drvdata)
{
struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
struct device *device = &drvdata->plat_dev->dev;
if (!ivgen_ctx)
return;
if (ivgen_ctx->pool_meta) {
memset(ivgen_ctx->pool_meta, 0, CC_IVPOOL_META_SIZE);
dma_free_coherent(device, CC_IVPOOL_META_SIZE,
ivgen_ctx->pool_meta,
ivgen_ctx->pool_meta_dma);
}
ivgen_ctx->pool = NULL_SRAM_ADDR;
/* release "this" context */
kfree(ivgen_ctx);
}
/*!
* Allocates iv-pool and maps resources.
* This function generates the first IV pool.
*
* \param drvdata Driver's private context
*
* \return int Zero for success, negative value otherwise.
*/
int cc_ivgen_init(struct cc_drvdata *drvdata)
{
struct cc_ivgen_ctx *ivgen_ctx;
struct device *device = &drvdata->plat_dev->dev;
int rc;
/* Allocate "this" context */
ivgen_ctx = kzalloc(sizeof(*ivgen_ctx), GFP_KERNEL);
if (!ivgen_ctx)
return -ENOMEM;
/* Allocate pool's header for initial enc. key/IV */
ivgen_ctx->pool_meta = dma_alloc_coherent(device, CC_IVPOOL_META_SIZE,
&ivgen_ctx->pool_meta_dma,
GFP_KERNEL);
if (!ivgen_ctx->pool_meta) {
dev_err(device, "Not enough memory to allocate DMA of pool_meta (%u B)\n",
CC_IVPOOL_META_SIZE);
rc = -ENOMEM;
goto out;
}
/* Allocate IV pool in SRAM */
ivgen_ctx->pool = cc_sram_alloc(drvdata, CC_IVPOOL_SIZE);
if (ivgen_ctx->pool == NULL_SRAM_ADDR) {
dev_err(device, "SRAM pool exhausted\n");
rc = -ENOMEM;
goto out;
}
drvdata->ivgen_handle = ivgen_ctx;
return cc_init_iv_sram(drvdata);
out:
cc_ivgen_fini(drvdata);
return rc;
}
/*!
* Acquires 16 Bytes IV from the iv-pool
*
* \param drvdata Driver private context
* \param iv_out_dma Array of physical IV out addresses
* \param iv_out_dma_len Length of iv_out_dma array (additional elements
* of iv_out_dma array are ignore)
* \param iv_out_size May be 8 or 16 bytes long
* \param iv_seq IN/OUT array to the descriptors sequence
* \param iv_seq_len IN/OUT pointer to the sequence length
*
* \return int Zero for success, negative value otherwise.
*/
int cc_get_iv(struct cc_drvdata *drvdata, dma_addr_t iv_out_dma[],
unsigned int iv_out_dma_len, unsigned int iv_out_size,
struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len)
{
struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
unsigned int idx = *iv_seq_len;
struct device *dev = drvdata_to_dev(drvdata);
unsigned int t;
if (iv_out_size != CC_AES_IV_SIZE &&
iv_out_size != CTR_RFC3686_IV_SIZE) {
return -EINVAL;
}
if ((iv_out_dma_len + 1) > CC_IVPOOL_SEQ_LEN) {
/* The sequence will be longer than allowed */
return -EINVAL;
}
/* check that number of generated IV is limited to max dma address
* iv buffer size
*/
if (iv_out_dma_len > CC_MAX_IVGEN_DMA_ADDRESSES) {
/* The sequence will be longer than allowed */
return -EINVAL;
}
for (t = 0; t < iv_out_dma_len; t++) {
/* Acquire IV from pool */
hw_desc_init(&iv_seq[idx]);
set_din_sram(&iv_seq[idx], (ivgen_ctx->pool +
ivgen_ctx->next_iv_ofs),
iv_out_size);
set_dout_dlli(&iv_seq[idx], iv_out_dma[t], iv_out_size,
NS_BIT, 0);
set_flow_mode(&iv_seq[idx], BYPASS);
idx++;
}
/* Bypass operation is proceeded by crypto sequence, hence must
* assure bypass-write-transaction by a memory barrier
*/
hw_desc_init(&iv_seq[idx]);
set_din_no_dma(&iv_seq[idx], 0, 0xfffff0);
set_dout_no_dma(&iv_seq[idx], 0, 0, 1);
idx++;
*iv_seq_len = idx; /* update seq length */
/* Update iv index */
ivgen_ctx->next_iv_ofs += iv_out_size;
if ((CC_IVPOOL_SIZE - ivgen_ctx->next_iv_ofs) < CC_AES_IV_SIZE) {
dev_dbg(dev, "Pool exhausted, regenerating iv-pool\n");
/* pool is drained -regenerate it! */
return cc_gen_iv_pool(ivgen_ctx, iv_seq, iv_seq_len);
}
return 0;
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef __CC_IVGEN_H__
#define __CC_IVGEN_H__
#include "cc_hw_queue_defs.h"
#define CC_IVPOOL_SEQ_LEN 8
/*!
* Allocates iv-pool and maps resources.
* This function generates the first IV pool.
*
* \param drvdata Driver's private context
*
* \return int Zero for success, negative value otherwise.
*/
int cc_ivgen_init(struct cc_drvdata *drvdata);
/*!
* Free iv-pool and ivgen context.
*
* \param drvdata
*/
void cc_ivgen_fini(struct cc_drvdata *drvdata);
/*!
* Generates the initial pool in SRAM.
* This function should be invoked when resuming DX driver.
*
* \param drvdata
*
* \return int Zero for success, negative value otherwise.
*/
int cc_init_iv_sram(struct cc_drvdata *drvdata);
/*!
* Acquires 16 Bytes IV from the iv-pool
*
* \param drvdata Driver private context
* \param iv_out_dma Array of physical IV out addresses
* \param iv_out_dma_len Length of iv_out_dma array (additional elements of
* iv_out_dma array are ignore)
* \param iv_out_size May be 8 or 16 bytes long
* \param iv_seq IN/OUT array to the descriptors sequence
* \param iv_seq_len IN/OUT pointer to the sequence length
*
* \return int Zero for success, negative value otherwise.
*/
int cc_get_iv(struct cc_drvdata *drvdata, dma_addr_t iv_out_dma[],
unsigned int iv_out_dma_len, unsigned int iv_out_size,
struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len);
#endif /*__CC_IVGEN_H__*/
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef __CC_CRYS_KERNEL_H__
#define __CC_CRYS_KERNEL_H__
// --------------------------------------
// BLOCK: DSCRPTR
// --------------------------------------
#define CC_DSCRPTR_COMPLETION_COUNTER_REG_OFFSET 0xE00UL
#define CC_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SIZE 0x6UL
#define CC_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SHIFT 0x6UL
#define CC_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SIZE 0x1UL
#define CC_DSCRPTR_SW_RESET_REG_OFFSET 0xE40UL
#define CC_DSCRPTR_SW_RESET_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_SW_RESET_VALUE_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_REG_OFFSET 0xE60UL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SIZE 0xAUL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SHIFT 0xAUL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SIZE 0xCUL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SHIFT 0x16UL
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SIZE 0x3UL
#define CC_DSCRPTR_SINGLE_ADDR_EN_REG_OFFSET 0xE64UL
#define CC_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SIZE 0x1UL
#define CC_DSCRPTR_MEASURE_CNTR_REG_OFFSET 0xE68UL
#define CC_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SIZE 0x20UL
#define CC_DSCRPTR_QUEUE_WORD0_REG_OFFSET 0xE80UL
#define CC_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SIZE 0x20UL
#define CC_DSCRPTR_QUEUE_WORD1_REG_OFFSET 0xE84UL
#define CC_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SHIFT 0x2UL
#define CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE 0x18UL
#define CC_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SHIFT 0x1AUL
#define CC_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SHIFT 0x1BUL
#define CC_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SHIFT 0x1CUL
#define CC_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SHIFT 0x1DUL
#define CC_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SHIFT 0x1EUL
#define CC_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD2_REG_OFFSET 0xE88UL
#define CC_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SIZE 0x20UL
#define CC_DSCRPTR_QUEUE_WORD3_REG_OFFSET 0xE8CUL
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SHIFT 0x2UL
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SIZE 0x18UL
#define CC_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SHIFT 0x1AUL
#define CC_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SHIFT 0x1BUL
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SHIFT 0x1DUL
#define CC_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SHIFT 0x1EUL
#define CC_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SHIFT 0x1FUL
#define CC_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_REG_OFFSET 0xE90UL
#define CC_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SIZE 0x6UL
#define CC_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SHIFT 0x6UL
#define CC_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SHIFT 0x7UL
#define CC_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SHIFT 0x8UL
#define CC_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SHIFT 0xAUL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SIZE 0x4UL
#define CC_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SHIFT 0xEUL
#define CC_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SHIFT 0xFUL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SHIFT 0x11UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SHIFT 0x13UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SHIFT 0x14UL
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SHIFT 0x16UL
#define CC_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SIZE 0x2UL
#define CC_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SHIFT 0x18UL
#define CC_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SIZE 0x4UL
#define CC_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SHIFT 0x1CUL
#define CC_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SHIFT 0x1DUL
#define CC_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SHIFT 0x1EUL
#define CC_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SHIFT 0x1FUL
#define CC_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SIZE 0x1UL
#define CC_DSCRPTR_QUEUE_WORD5_REG_OFFSET 0xE94UL
#define CC_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SIZE 0x10UL
#define CC_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SHIFT 0x10UL
#define CC_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SIZE 0x10UL
#define CC_DSCRPTR_QUEUE_WATERMARK_REG_OFFSET 0xE98UL
#define CC_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SIZE 0xAUL
#define CC_DSCRPTR_QUEUE_CONTENT_REG_OFFSET 0xE9CUL
#define CC_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SHIFT 0x0UL
#define CC_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SIZE 0xAUL
// --------------------------------------
// BLOCK: AXI_P
// --------------------------------------
#define CC_AXIM_MON_INFLIGHT_REG_OFFSET 0xB00UL
#define CC_AXIM_MON_INFLIGHT_VALUE_BIT_SHIFT 0x0UL
#define CC_AXIM_MON_INFLIGHT_VALUE_BIT_SIZE 0x8UL
#define CC_AXIM_MON_INFLIGHTLAST_REG_OFFSET 0xB40UL
#define CC_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SHIFT 0x0UL
#define CC_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SIZE 0x8UL
#define CC_AXIM_MON_COMP_REG_OFFSET 0xB80UL
#define CC_AXIM_MON_COMP_VALUE_BIT_SHIFT 0x0UL
#define CC_AXIM_MON_COMP_VALUE_BIT_SIZE 0x10UL
#define CC_AXIM_MON_ERR_REG_OFFSET 0xBC4UL
#define CC_AXIM_MON_ERR_BRESP_BIT_SHIFT 0x0UL
#define CC_AXIM_MON_ERR_BRESP_BIT_SIZE 0x2UL
#define CC_AXIM_MON_ERR_BID_BIT_SHIFT 0x2UL
#define CC_AXIM_MON_ERR_BID_BIT_SIZE 0x4UL
#define CC_AXIM_MON_ERR_RRESP_BIT_SHIFT 0x10UL
#define CC_AXIM_MON_ERR_RRESP_BIT_SIZE 0x2UL
#define CC_AXIM_MON_ERR_RID_BIT_SHIFT 0x12UL
#define CC_AXIM_MON_ERR_RID_BIT_SIZE 0x4UL
#define CC_AXIM_CFG_REG_OFFSET 0xBE8UL
#define CC_AXIM_CFG_BRESPMASK_BIT_SHIFT 0x4UL
#define CC_AXIM_CFG_BRESPMASK_BIT_SIZE 0x1UL
#define CC_AXIM_CFG_RRESPMASK_BIT_SHIFT 0x5UL
#define CC_AXIM_CFG_RRESPMASK_BIT_SIZE 0x1UL
#define CC_AXIM_CFG_INFLTMASK_BIT_SHIFT 0x6UL
#define CC_AXIM_CFG_INFLTMASK_BIT_SIZE 0x1UL
#define CC_AXIM_CFG_COMPMASK_BIT_SHIFT 0x7UL
#define CC_AXIM_CFG_COMPMASK_BIT_SIZE 0x1UL
#define CC_AXIM_ACE_CONST_REG_OFFSET 0xBECUL
#define CC_AXIM_ACE_CONST_ARDOMAIN_BIT_SHIFT 0x0UL
#define CC_AXIM_ACE_CONST_ARDOMAIN_BIT_SIZE 0x2UL
#define CC_AXIM_ACE_CONST_AWDOMAIN_BIT_SHIFT 0x2UL
#define CC_AXIM_ACE_CONST_AWDOMAIN_BIT_SIZE 0x2UL
#define CC_AXIM_ACE_CONST_ARBAR_BIT_SHIFT 0x4UL
#define CC_AXIM_ACE_CONST_ARBAR_BIT_SIZE 0x2UL
#define CC_AXIM_ACE_CONST_AWBAR_BIT_SHIFT 0x6UL
#define CC_AXIM_ACE_CONST_AWBAR_BIT_SIZE 0x2UL
#define CC_AXIM_ACE_CONST_ARSNOOP_BIT_SHIFT 0x8UL
#define CC_AXIM_ACE_CONST_ARSNOOP_BIT_SIZE 0x4UL
#define CC_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SHIFT 0xCUL
#define CC_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SIZE 0x3UL
#define CC_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SHIFT 0xFUL
#define CC_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SIZE 0x3UL
#define CC_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SHIFT 0x12UL
#define CC_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SIZE 0x7UL
#define CC_AXIM_ACE_CONST_AWLEN_VAL_BIT_SHIFT 0x19UL
#define CC_AXIM_ACE_CONST_AWLEN_VAL_BIT_SIZE 0x4UL
#define CC_AXIM_CACHE_PARAMS_REG_OFFSET 0xBF0UL
#define CC_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SHIFT 0x0UL
#define CC_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SIZE 0x4UL
#define CC_AXIM_CACHE_PARAMS_AWCACHE_BIT_SHIFT 0x4UL
#define CC_AXIM_CACHE_PARAMS_AWCACHE_BIT_SIZE 0x4UL
#define CC_AXIM_CACHE_PARAMS_ARCACHE_BIT_SHIFT 0x8UL
#define CC_AXIM_CACHE_PARAMS_ARCACHE_BIT_SIZE 0x4UL
#endif // __CC_CRYS_KERNEL_H__
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef _CC_LLI_DEFS_H_
#define _CC_LLI_DEFS_H_
#include <linux/types.h>
/* Max DLLI size
* AKA CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE
*/
#define DLLI_SIZE_BIT_SIZE 0x18
#define CC_MAX_MLLI_ENTRY_SIZE 0xFFFF
#define LLI_MAX_NUM_OF_DATA_ENTRIES 128
#define LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES 4
#define MLLI_TABLE_MIN_ALIGNMENT 4 /* 32 bit alignment */
#define MAX_NUM_OF_BUFFERS_IN_MLLI 4
#define MAX_NUM_OF_TOTAL_MLLI_ENTRIES \
(2 * LLI_MAX_NUM_OF_DATA_ENTRIES + \
LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES)
/* Size of entry */
#define LLI_ENTRY_WORD_SIZE 2
#define LLI_ENTRY_BYTE_SIZE (LLI_ENTRY_WORD_SIZE * sizeof(u32))
/* Word0[31:0] = ADDR[31:0] */
#define LLI_WORD0_OFFSET 0
#define LLI_LADDR_BIT_OFFSET 0
#define LLI_LADDR_BIT_SIZE 32
/* Word1[31:16] = ADDR[47:32]; Word1[15:0] = SIZE */
#define LLI_WORD1_OFFSET 1
#define LLI_SIZE_BIT_OFFSET 0
#define LLI_SIZE_BIT_SIZE 16
#define LLI_HADDR_BIT_OFFSET 16
#define LLI_HADDR_BIT_SIZE 16
#define LLI_SIZE_MASK GENMASK((LLI_SIZE_BIT_SIZE - 1), LLI_SIZE_BIT_OFFSET)
#define LLI_HADDR_MASK GENMASK( \
(LLI_HADDR_BIT_OFFSET + LLI_HADDR_BIT_SIZE - 1),\
LLI_HADDR_BIT_OFFSET)
static inline void cc_lli_set_addr(u32 *lli_p, dma_addr_t addr)
{
lli_p[LLI_WORD0_OFFSET] = (addr & U32_MAX);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
lli_p[LLI_WORD1_OFFSET] &= ~LLI_HADDR_MASK;
lli_p[LLI_WORD1_OFFSET] |= FIELD_PREP(LLI_HADDR_MASK, (addr >> 32));
#endif /* CONFIG_ARCH_DMA_ADDR_T_64BIT */
}
static inline void cc_lli_set_size(u32 *lli_p, u16 size)
{
lli_p[LLI_WORD1_OFFSET] &= ~LLI_SIZE_MASK;
lli_p[LLI_WORD1_OFFSET] |= FIELD_PREP(LLI_SIZE_MASK, size);
}
#endif /*_CC_LLI_DEFS_H_*/
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include "cc_driver.h"
#include "cc_buffer_mgr.h"
#include "cc_request_mgr.h"
#include "cc_sram_mgr.h"
#include "cc_ivgen.h"
#include "cc_pm.h"
#define POWER_DOWN_ENABLE 0x01
#define POWER_DOWN_DISABLE 0x00
const struct dev_pm_ops ccree_pm = {
SET_RUNTIME_PM_OPS(cc_pm_suspend, cc_pm_resume, NULL)
};
int cc_pm_suspend(struct device *dev)
{
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
int rc;
dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE);
rc = cc_suspend_req_queue(drvdata);
if (rc) {
dev_err(dev, "cc_suspend_req_queue (%x)\n", rc);
return rc;
}
fini_cc_regs(drvdata);
cc_clk_off(drvdata);
return 0;
}
int cc_pm_resume(struct device *dev)
{
int rc;
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n");
cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE);
rc = cc_clk_on(drvdata);
if (rc) {
dev_err(dev, "failed getting clock back on. We're toast.\n");
return rc;
}
rc = init_cc_regs(drvdata, false);
if (rc) {
dev_err(dev, "init_cc_regs (%x)\n", rc);
return rc;
}
rc = cc_resume_req_queue(drvdata);
if (rc) {
dev_err(dev, "cc_resume_req_queue (%x)\n", rc);
return rc;
}
cc_init_iv_sram(drvdata);
return 0;
}
int cc_pm_get(struct device *dev)
{
int rc = 0;
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
if (cc_req_queue_suspended(drvdata))
rc = pm_runtime_get_sync(dev);
else
pm_runtime_get_noresume(dev);
return rc;
}
int cc_pm_put_suspend(struct device *dev)
{
int rc = 0;
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
if (!cc_req_queue_suspended(drvdata)) {
pm_runtime_mark_last_busy(dev);
rc = pm_runtime_put_autosuspend(dev);
} else {
/* Something wrong happens*/
dev_err(dev, "request to suspend already suspended queue");
rc = -EBUSY;
}
return rc;
}
int cc_pm_init(struct cc_drvdata *drvdata)
{
int rc = 0;
struct device *dev = drvdata_to_dev(drvdata);
/* must be before the enabling to avoid resdundent suspending */
pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(dev);
/* activate the PM module */
rc = pm_runtime_set_active(dev);
if (rc)
return rc;
/* enable the PM module*/
pm_runtime_enable(dev);
return rc;
}
void cc_pm_fini(struct cc_drvdata *drvdata)
{
pm_runtime_disable(drvdata_to_dev(drvdata));
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
/* \file cc_pm.h
*/
#ifndef __CC_POWER_MGR_H__
#define __CC_POWER_MGR_H__
#include "cc_driver.h"
#define CC_SUSPEND_TIMEOUT 3000
#if defined(CONFIG_PM)
extern const struct dev_pm_ops ccree_pm;
int cc_pm_init(struct cc_drvdata *drvdata);
void cc_pm_fini(struct cc_drvdata *drvdata);
int cc_pm_suspend(struct device *dev);
int cc_pm_resume(struct device *dev);
int cc_pm_get(struct device *dev);
int cc_pm_put_suspend(struct device *dev);
#else
static inline int cc_pm_init(struct cc_drvdata *drvdata)
{
return 0;
}
static inline void cc_pm_fini(struct cc_drvdata *drvdata) {}
static inline int cc_pm_suspend(struct device *dev)
{
return 0;
}
static inline int cc_pm_resume(struct device *dev)
{
return 0;
}
static inline int cc_pm_get(struct device *dev)
{
return 0;
}
static inline int cc_pm_put_suspend(struct device *dev)
{
return 0;
}
#endif
#endif /*__POWER_MGR_H__*/
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
/* \file cc_request_mgr.h
* Request Manager
*/
#ifndef __REQUEST_MGR_H__
#define __REQUEST_MGR_H__
#include "cc_hw_queue_defs.h"
int cc_req_mgr_init(struct cc_drvdata *drvdata);
/*!
* Enqueue caller request to crypto hardware.
*
* \param drvdata
* \param cc_req The request to enqueue
* \param desc The crypto sequence
* \param len The crypto sequence length
* \param is_dout If "true": completion is handled by the caller
* If "false": this function adds a dummy descriptor completion
* and waits upon completion signal.
*
* \return int Returns -EINPROGRESS or error
*/
int cc_send_request(struct cc_drvdata *drvdata, struct cc_crypto_req *cc_req,
struct cc_hw_desc *desc, unsigned int len,
struct crypto_async_request *req);
int cc_send_sync_request(struct cc_drvdata *drvdata,
struct cc_crypto_req *cc_req, struct cc_hw_desc *desc,
unsigned int len);
int send_request_init(struct cc_drvdata *drvdata, struct cc_hw_desc *desc,
unsigned int len);
void complete_request(struct cc_drvdata *drvdata);
void cc_req_mgr_fini(struct cc_drvdata *drvdata);
#if defined(CONFIG_PM)
int cc_resume_req_queue(struct cc_drvdata *drvdata);
int cc_suspend_req_queue(struct cc_drvdata *drvdata);
bool cc_req_queue_suspended(struct cc_drvdata *drvdata);
#endif
#endif /*__REQUEST_MGR_H__*/
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#include "cc_driver.h"
#include "cc_sram_mgr.h"
/**
* struct cc_sram_ctx -Internal RAM context manager
* @sram_free_offset: the offset to the non-allocated area
*/
struct cc_sram_ctx {
cc_sram_addr_t sram_free_offset;
};
/**
* cc_sram_mgr_fini() - Cleanup SRAM pool.
*
* @drvdata: Associated device driver context
*/
void cc_sram_mgr_fini(struct cc_drvdata *drvdata)
{
/* Free "this" context */
kfree(drvdata->sram_mgr_handle);
}
/**
* cc_sram_mgr_init() - Initializes SRAM pool.
* The pool starts right at the beginning of SRAM.
* Returns zero for success, negative value otherwise.
*
* @drvdata: Associated device driver context
*/
int cc_sram_mgr_init(struct cc_drvdata *drvdata)
{
struct cc_sram_ctx *ctx;
/* Allocate "this" context */
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
drvdata->sram_mgr_handle = ctx;
return 0;
}
/*!
* Allocated buffer from SRAM pool.
* Note: Caller is responsible to free the LAST allocated buffer.
* This function does not taking care of any fragmentation may occur
* by the order of calls to alloc/free.
*
* \param drvdata
* \param size The requested bytes to allocate
*/
cc_sram_addr_t cc_sram_alloc(struct cc_drvdata *drvdata, u32 size)
{
struct cc_sram_ctx *smgr_ctx = drvdata->sram_mgr_handle;
struct device *dev = drvdata_to_dev(drvdata);
cc_sram_addr_t p;
if ((size & 0x3)) {
dev_err(dev, "Requested buffer size (%u) is not multiple of 4",
size);
return NULL_SRAM_ADDR;
}
if (size > (CC_CC_SRAM_SIZE - smgr_ctx->sram_free_offset)) {
dev_err(dev, "Not enough space to allocate %u B (at offset %llu)\n",
size, smgr_ctx->sram_free_offset);
return NULL_SRAM_ADDR;
}
p = smgr_ctx->sram_free_offset;
smgr_ctx->sram_free_offset += size;
dev_dbg(dev, "Allocated %u B @ %u\n", size, (unsigned int)p);
return p;
}
/**
* cc_set_sram_desc() - Create const descriptors sequence to
* set values in given array into SRAM.
* Note: each const value can't exceed word size.
*
* @src: A pointer to array of words to set as consts.
* @dst: The target SRAM buffer to set into
* @nelements: The number of words in "src" array
* @seq: A pointer to the given IN/OUT descriptor sequence
* @seq_len: A pointer to the given IN/OUT sequence length
*/
void cc_set_sram_desc(const u32 *src, cc_sram_addr_t dst,
unsigned int nelement, struct cc_hw_desc *seq,
unsigned int *seq_len)
{
u32 i;
unsigned int idx = *seq_len;
for (i = 0; i < nelement; i++, idx++) {
hw_desc_init(&seq[idx]);
set_din_const(&seq[idx], src[i], sizeof(u32));
set_dout_sram(&seq[idx], dst + (i * sizeof(u32)), sizeof(u32));
set_flow_mode(&seq[idx], BYPASS);
}
*seq_len = idx;
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#ifndef __CC_SRAM_MGR_H__
#define __CC_SRAM_MGR_H__
#ifndef CC_CC_SRAM_SIZE
#define CC_CC_SRAM_SIZE 4096
#endif
struct cc_drvdata;
/**
* Address (offset) within CC internal SRAM
*/
typedef u64 cc_sram_addr_t;
#define NULL_SRAM_ADDR ((cc_sram_addr_t)-1)
/*!
* Initializes SRAM pool.
* The first X bytes of SRAM are reserved for ROM usage, hence, pool
* starts right after X bytes.
*
* \param drvdata
*
* \return int Zero for success, negative value otherwise.
*/
int cc_sram_mgr_init(struct cc_drvdata *drvdata);
/*!
* Uninits SRAM pool.
*
* \param drvdata
*/
void cc_sram_mgr_fini(struct cc_drvdata *drvdata);
/*!
* Allocated buffer from SRAM pool.
* Note: Caller is responsible to free the LAST allocated buffer.
* This function does not taking care of any fragmentation may occur
* by the order of calls to alloc/free.
*
* \param drvdata
* \param size The requested bytes to allocate
*/
cc_sram_addr_t cc_sram_alloc(struct cc_drvdata *drvdata, u32 size);
/**
* cc_set_sram_desc() - Create const descriptors sequence to
* set values in given array into SRAM.
* Note: each const value can't exceed word size.
*
* @src: A pointer to array of words to set as consts.
* @dst: The target SRAM buffer to set into
* @nelements: The number of words in "src" array
* @seq: A pointer to the given IN/OUT descriptor sequence
* @seq_len: A pointer to the given IN/OUT sequence length
*/
void cc_set_sram_desc(const u32 *src, cc_sram_addr_t dst,
unsigned int nelement, struct cc_hw_desc *seq,
unsigned int *seq_len);
#endif /*__CC_SRAM_MGR_H__*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment