162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
262306a36Sopenharmony_ci#ifndef __ASPEED_HACE_H__
362306a36Sopenharmony_ci#define __ASPEED_HACE_H__
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <crypto/aes.h>
662306a36Sopenharmony_ci#include <crypto/engine.h>
762306a36Sopenharmony_ci#include <crypto/hash.h>
862306a36Sopenharmony_ci#include <crypto/sha2.h>
962306a36Sopenharmony_ci#include <linux/bits.h>
1062306a36Sopenharmony_ci#include <linux/compiler_attributes.h>
1162306a36Sopenharmony_ci#include <linux/interrupt.h>
1262306a36Sopenharmony_ci#include <linux/types.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*****************************
1562306a36Sopenharmony_ci *                           *
1662306a36Sopenharmony_ci * HACE register definitions *
1762306a36Sopenharmony_ci *                           *
1862306a36Sopenharmony_ci * ***************************/
1962306a36Sopenharmony_ci#define ASPEED_HACE_SRC			0x00	/* Crypto Data Source Base Address Register */
2062306a36Sopenharmony_ci#define ASPEED_HACE_DEST		0x04	/* Crypto Data Destination Base Address Register */
2162306a36Sopenharmony_ci#define ASPEED_HACE_CONTEXT		0x08	/* Crypto Context Buffer Base Address Register */
2262306a36Sopenharmony_ci#define ASPEED_HACE_DATA_LEN		0x0C	/* Crypto Data Length Register */
2362306a36Sopenharmony_ci#define ASPEED_HACE_CMD			0x10	/* Crypto Engine Command Register */
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* G5 */
2662306a36Sopenharmony_ci#define ASPEED_HACE_TAG			0x18	/* HACE Tag Register */
2762306a36Sopenharmony_ci/* G6 */
2862306a36Sopenharmony_ci#define ASPEED_HACE_GCM_ADD_LEN		0x14	/* Crypto AES-GCM Additional Data Length Register */
2962306a36Sopenharmony_ci#define ASPEED_HACE_GCM_TAG_BASE_ADDR	0x18	/* Crypto AES-GCM Tag Write Buff Base Address Reg */
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define ASPEED_HACE_STS			0x1C	/* HACE Status Register */
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define ASPEED_HACE_HASH_SRC		0x20	/* Hash Data Source Base Address Register */
3462306a36Sopenharmony_ci#define ASPEED_HACE_HASH_DIGEST_BUFF	0x24	/* Hash Digest Write Buffer Base Address Register */
3562306a36Sopenharmony_ci#define ASPEED_HACE_HASH_KEY_BUFF	0x28	/* Hash HMAC Key Buffer Base Address Register */
3662306a36Sopenharmony_ci#define ASPEED_HACE_HASH_DATA_LEN	0x2C	/* Hash Data Length Register */
3762306a36Sopenharmony_ci#define ASPEED_HACE_HASH_CMD		0x30	/* Hash Engine Command Register */
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* crypto cmd */
4062306a36Sopenharmony_ci#define  HACE_CMD_SINGLE_DES		0
4162306a36Sopenharmony_ci#define  HACE_CMD_TRIPLE_DES		BIT(17)
4262306a36Sopenharmony_ci#define  HACE_CMD_AES_SELECT		0
4362306a36Sopenharmony_ci#define  HACE_CMD_DES_SELECT		BIT(16)
4462306a36Sopenharmony_ci#define  HACE_CMD_ISR_EN		BIT(12)
4562306a36Sopenharmony_ci#define  HACE_CMD_CONTEXT_SAVE_ENABLE	(0)
4662306a36Sopenharmony_ci#define  HACE_CMD_CONTEXT_SAVE_DISABLE	BIT(9)
4762306a36Sopenharmony_ci#define  HACE_CMD_AES			(0)
4862306a36Sopenharmony_ci#define  HACE_CMD_DES			(0)
4962306a36Sopenharmony_ci#define  HACE_CMD_RC4			BIT(8)
5062306a36Sopenharmony_ci#define  HACE_CMD_DECRYPT		(0)
5162306a36Sopenharmony_ci#define  HACE_CMD_ENCRYPT		BIT(7)
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#define  HACE_CMD_ECB			(0x0 << 4)
5462306a36Sopenharmony_ci#define  HACE_CMD_CBC			(0x1 << 4)
5562306a36Sopenharmony_ci#define  HACE_CMD_CFB			(0x2 << 4)
5662306a36Sopenharmony_ci#define  HACE_CMD_OFB			(0x3 << 4)
5762306a36Sopenharmony_ci#define  HACE_CMD_CTR			(0x4 << 4)
5862306a36Sopenharmony_ci#define  HACE_CMD_OP_MODE_MASK		(0x7 << 4)
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define  HACE_CMD_AES128		(0x0 << 2)
6162306a36Sopenharmony_ci#define  HACE_CMD_AES192		(0x1 << 2)
6262306a36Sopenharmony_ci#define  HACE_CMD_AES256		(0x2 << 2)
6362306a36Sopenharmony_ci#define  HACE_CMD_OP_CASCADE		(0x3)
6462306a36Sopenharmony_ci#define  HACE_CMD_OP_INDEPENDENT	(0x1)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* G5 */
6762306a36Sopenharmony_ci#define  HACE_CMD_RI_WO_DATA_ENABLE	(0)
6862306a36Sopenharmony_ci#define  HACE_CMD_RI_WO_DATA_DISABLE	BIT(11)
6962306a36Sopenharmony_ci#define  HACE_CMD_CONTEXT_LOAD_ENABLE	(0)
7062306a36Sopenharmony_ci#define  HACE_CMD_CONTEXT_LOAD_DISABLE	BIT(10)
7162306a36Sopenharmony_ci/* G6 */
7262306a36Sopenharmony_ci#define  HACE_CMD_AES_KEY_FROM_OTP	BIT(24)
7362306a36Sopenharmony_ci#define  HACE_CMD_GHASH_TAG_XOR_EN	BIT(23)
7462306a36Sopenharmony_ci#define  HACE_CMD_GHASH_PAD_LEN_INV	BIT(22)
7562306a36Sopenharmony_ci#define  HACE_CMD_GCM_TAG_ADDR_SEL	BIT(21)
7662306a36Sopenharmony_ci#define  HACE_CMD_MBUS_REQ_SYNC_EN	BIT(20)
7762306a36Sopenharmony_ci#define  HACE_CMD_DES_SG_CTRL		BIT(19)
7862306a36Sopenharmony_ci#define  HACE_CMD_SRC_SG_CTRL		BIT(18)
7962306a36Sopenharmony_ci#define  HACE_CMD_CTR_IV_AES_96		(0x1 << 14)
8062306a36Sopenharmony_ci#define  HACE_CMD_CTR_IV_DES_32		(0x1 << 14)
8162306a36Sopenharmony_ci#define  HACE_CMD_CTR_IV_AES_64		(0x2 << 14)
8262306a36Sopenharmony_ci#define  HACE_CMD_CTR_IV_AES_32		(0x3 << 14)
8362306a36Sopenharmony_ci#define  HACE_CMD_AES_KEY_HW_EXP	BIT(13)
8462306a36Sopenharmony_ci#define  HACE_CMD_GCM			(0x5 << 4)
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* interrupt status reg */
8762306a36Sopenharmony_ci#define  HACE_CRYPTO_ISR		BIT(12)
8862306a36Sopenharmony_ci#define  HACE_HASH_ISR			BIT(9)
8962306a36Sopenharmony_ci#define  HACE_HASH_BUSY			BIT(0)
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* hash cmd reg */
9262306a36Sopenharmony_ci#define  HASH_CMD_MBUS_REQ_SYNC_EN	BIT(20)
9362306a36Sopenharmony_ci#define  HASH_CMD_HASH_SRC_SG_CTRL	BIT(18)
9462306a36Sopenharmony_ci#define  HASH_CMD_SHA512_224		(0x3 << 10)
9562306a36Sopenharmony_ci#define  HASH_CMD_SHA512_256		(0x2 << 10)
9662306a36Sopenharmony_ci#define  HASH_CMD_SHA384		(0x1 << 10)
9762306a36Sopenharmony_ci#define  HASH_CMD_SHA512		(0)
9862306a36Sopenharmony_ci#define  HASH_CMD_INT_ENABLE		BIT(9)
9962306a36Sopenharmony_ci#define  HASH_CMD_HMAC			(0x1 << 7)
10062306a36Sopenharmony_ci#define  HASH_CMD_ACC_MODE		(0x2 << 7)
10162306a36Sopenharmony_ci#define  HASH_CMD_HMAC_KEY		(0x3 << 7)
10262306a36Sopenharmony_ci#define  HASH_CMD_SHA1			(0x2 << 4)
10362306a36Sopenharmony_ci#define  HASH_CMD_SHA224		(0x4 << 4)
10462306a36Sopenharmony_ci#define  HASH_CMD_SHA256		(0x5 << 4)
10562306a36Sopenharmony_ci#define  HASH_CMD_SHA512_SER		(0x6 << 4)
10662306a36Sopenharmony_ci#define  HASH_CMD_SHA_SWAP		(0x2 << 2)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#define HASH_SG_LAST_LIST		BIT(31)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#define CRYPTO_FLAGS_BUSY		BIT(1)
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci#define SHA_OP_UPDATE			1
11362306a36Sopenharmony_ci#define SHA_OP_FINAL			2
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci#define SHA_FLAGS_SHA1			BIT(0)
11662306a36Sopenharmony_ci#define SHA_FLAGS_SHA224		BIT(1)
11762306a36Sopenharmony_ci#define SHA_FLAGS_SHA256		BIT(2)
11862306a36Sopenharmony_ci#define SHA_FLAGS_SHA384		BIT(3)
11962306a36Sopenharmony_ci#define SHA_FLAGS_SHA512		BIT(4)
12062306a36Sopenharmony_ci#define SHA_FLAGS_SHA512_224		BIT(5)
12162306a36Sopenharmony_ci#define SHA_FLAGS_SHA512_256		BIT(6)
12262306a36Sopenharmony_ci#define SHA_FLAGS_HMAC			BIT(8)
12362306a36Sopenharmony_ci#define SHA_FLAGS_FINUP			BIT(9)
12462306a36Sopenharmony_ci#define SHA_FLAGS_MASK			(0xff)
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#define ASPEED_CRYPTO_SRC_DMA_BUF_LEN	0xa000
12762306a36Sopenharmony_ci#define ASPEED_CRYPTO_DST_DMA_BUF_LEN	0xa000
12862306a36Sopenharmony_ci#define ASPEED_CRYPTO_GCM_TAG_OFFSET	0x9ff0
12962306a36Sopenharmony_ci#define ASPEED_HASH_SRC_DMA_BUF_LEN	0xa000
13062306a36Sopenharmony_ci#define ASPEED_HASH_QUEUE_LENGTH	50
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#define HACE_CMD_IV_REQUIRE		(HACE_CMD_CBC | HACE_CMD_CFB | \
13362306a36Sopenharmony_ci					 HACE_CMD_OFB | HACE_CMD_CTR)
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistruct aspeed_hace_dev;
13662306a36Sopenharmony_cistruct scatterlist;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_citypedef int (*aspeed_hace_fn_t)(struct aspeed_hace_dev *);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistruct aspeed_sg_list {
14162306a36Sopenharmony_ci	__le32 len;
14262306a36Sopenharmony_ci	__le32 phy_addr;
14362306a36Sopenharmony_ci};
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_cistruct aspeed_engine_hash {
14662306a36Sopenharmony_ci	struct tasklet_struct		done_task;
14762306a36Sopenharmony_ci	unsigned long			flags;
14862306a36Sopenharmony_ci	struct ahash_request		*req;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	/* input buffer */
15162306a36Sopenharmony_ci	void				*ahash_src_addr;
15262306a36Sopenharmony_ci	dma_addr_t			ahash_src_dma_addr;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	dma_addr_t			src_dma;
15562306a36Sopenharmony_ci	dma_addr_t			digest_dma;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	size_t				src_length;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	/* callback func */
16062306a36Sopenharmony_ci	aspeed_hace_fn_t		resume;
16162306a36Sopenharmony_ci	aspeed_hace_fn_t		dma_prepare;
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistruct aspeed_sha_hmac_ctx {
16562306a36Sopenharmony_ci	struct crypto_shash *shash;
16662306a36Sopenharmony_ci	u8 ipad[SHA512_BLOCK_SIZE];
16762306a36Sopenharmony_ci	u8 opad[SHA512_BLOCK_SIZE];
16862306a36Sopenharmony_ci};
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistruct aspeed_sham_ctx {
17162306a36Sopenharmony_ci	struct aspeed_hace_dev		*hace_dev;
17262306a36Sopenharmony_ci	unsigned long			flags;	/* hmac flag */
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	struct aspeed_sha_hmac_ctx	base[];
17562306a36Sopenharmony_ci};
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistruct aspeed_sham_reqctx {
17862306a36Sopenharmony_ci	unsigned long		flags;		/* final update flag should no use*/
17962306a36Sopenharmony_ci	unsigned long		op;		/* final or update */
18062306a36Sopenharmony_ci	u32			cmd;		/* trigger cmd */
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	/* walk state */
18362306a36Sopenharmony_ci	struct scatterlist	*src_sg;
18462306a36Sopenharmony_ci	int			src_nents;
18562306a36Sopenharmony_ci	unsigned int		offset;		/* offset in current sg */
18662306a36Sopenharmony_ci	unsigned int		total;		/* per update length */
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	size_t			digsize;
18962306a36Sopenharmony_ci	size_t			block_size;
19062306a36Sopenharmony_ci	size_t			ivsize;
19162306a36Sopenharmony_ci	const __be32		*sha_iv;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	/* remain data buffer */
19462306a36Sopenharmony_ci	u8			buffer[SHA512_BLOCK_SIZE * 2];
19562306a36Sopenharmony_ci	dma_addr_t		buffer_dma_addr;
19662306a36Sopenharmony_ci	size_t			bufcnt;		/* buffer counter */
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	/* output buffer */
19962306a36Sopenharmony_ci	u8			digest[SHA512_DIGEST_SIZE] __aligned(64);
20062306a36Sopenharmony_ci	dma_addr_t		digest_dma_addr;
20162306a36Sopenharmony_ci	u64			digcnt[2];
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_cistruct aspeed_engine_crypto {
20562306a36Sopenharmony_ci	struct tasklet_struct		done_task;
20662306a36Sopenharmony_ci	unsigned long			flags;
20762306a36Sopenharmony_ci	struct skcipher_request		*req;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/* context buffer */
21062306a36Sopenharmony_ci	void				*cipher_ctx;
21162306a36Sopenharmony_ci	dma_addr_t			cipher_ctx_dma;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	/* input buffer, could be single/scatter-gather lists */
21462306a36Sopenharmony_ci	void				*cipher_addr;
21562306a36Sopenharmony_ci	dma_addr_t			cipher_dma_addr;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	/* output buffer, only used in scatter-gather lists */
21862306a36Sopenharmony_ci	void				*dst_sg_addr;
21962306a36Sopenharmony_ci	dma_addr_t			dst_sg_dma_addr;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	/* callback func */
22262306a36Sopenharmony_ci	aspeed_hace_fn_t		resume;
22362306a36Sopenharmony_ci};
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cistruct aspeed_cipher_ctx {
22662306a36Sopenharmony_ci	struct aspeed_hace_dev		*hace_dev;
22762306a36Sopenharmony_ci	int				key_len;
22862306a36Sopenharmony_ci	u8				key[AES_MAX_KEYLENGTH];
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	/* callback func */
23162306a36Sopenharmony_ci	aspeed_hace_fn_t		start;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	struct crypto_skcipher          *fallback_tfm;
23462306a36Sopenharmony_ci};
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistruct aspeed_cipher_reqctx {
23762306a36Sopenharmony_ci	int enc_cmd;
23862306a36Sopenharmony_ci	int src_nents;
23962306a36Sopenharmony_ci	int dst_nents;
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci	struct skcipher_request         fallback_req;   /* keep at the end */
24262306a36Sopenharmony_ci};
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cistruct aspeed_hace_dev {
24562306a36Sopenharmony_ci	void __iomem			*regs;
24662306a36Sopenharmony_ci	struct device			*dev;
24762306a36Sopenharmony_ci	int				irq;
24862306a36Sopenharmony_ci	struct clk			*clk;
24962306a36Sopenharmony_ci	unsigned long			version;
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	struct crypto_engine		*crypt_engine_hash;
25262306a36Sopenharmony_ci	struct crypto_engine		*crypt_engine_crypto;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	struct aspeed_engine_hash	hash_engine;
25562306a36Sopenharmony_ci	struct aspeed_engine_crypto	crypto_engine;
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistruct aspeed_hace_alg {
25962306a36Sopenharmony_ci	struct aspeed_hace_dev		*hace_dev;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	const char			*alg_base;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	union {
26462306a36Sopenharmony_ci		struct skcipher_engine_alg skcipher;
26562306a36Sopenharmony_ci		struct ahash_engine_alg ahash;
26662306a36Sopenharmony_ci	} alg;
26762306a36Sopenharmony_ci};
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cienum aspeed_version {
27062306a36Sopenharmony_ci	AST2500_VERSION = 5,
27162306a36Sopenharmony_ci	AST2600_VERSION
27262306a36Sopenharmony_ci};
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci#define ast_hace_write(hace, val, offset)	\
27562306a36Sopenharmony_ci	writel((val), (hace)->regs + (offset))
27662306a36Sopenharmony_ci#define ast_hace_read(hace, offset)		\
27762306a36Sopenharmony_ci	readl((hace)->regs + (offset))
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_civoid aspeed_register_hace_hash_algs(struct aspeed_hace_dev *hace_dev);
28062306a36Sopenharmony_civoid aspeed_unregister_hace_hash_algs(struct aspeed_hace_dev *hace_dev);
28162306a36Sopenharmony_civoid aspeed_register_hace_crypto_algs(struct aspeed_hace_dev *hace_dev);
28262306a36Sopenharmony_civoid aspeed_unregister_hace_crypto_algs(struct aspeed_hace_dev *hace_dev);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci#endif
285