1108713a7SNeal Liu /* SPDX-License-Identifier: GPL-2.0+ */
2108713a7SNeal Liu #ifndef __ASPEED_HACE_H__
3108713a7SNeal Liu #define __ASPEED_HACE_H__
4108713a7SNeal Liu 
562f58b16SNeal Liu #include <crypto/aes.h>
6108713a7SNeal Liu #include <crypto/engine.h>
7*304506f2SHerbert Xu #include <crypto/hash.h>
8108713a7SNeal Liu #include <crypto/sha2.h>
9*304506f2SHerbert Xu #include <linux/bits.h>
10*304506f2SHerbert Xu #include <linux/compiler_attributes.h>
11*304506f2SHerbert Xu #include <linux/interrupt.h>
12*304506f2SHerbert Xu #include <linux/types.h>
13108713a7SNeal Liu 
14108713a7SNeal Liu /*****************************
15108713a7SNeal Liu  *                           *
16108713a7SNeal Liu  * HACE register definitions *
17108713a7SNeal Liu  *                           *
18108713a7SNeal Liu  * ***************************/
1962f58b16SNeal Liu #define ASPEED_HACE_SRC			0x00	/* Crypto Data Source Base Address Register */
2062f58b16SNeal Liu #define ASPEED_HACE_DEST		0x04	/* Crypto Data Destination Base Address Register */
2162f58b16SNeal Liu #define ASPEED_HACE_CONTEXT		0x08	/* Crypto Context Buffer Base Address Register */
2262f58b16SNeal Liu #define ASPEED_HACE_DATA_LEN		0x0C	/* Crypto Data Length Register */
2362f58b16SNeal Liu #define ASPEED_HACE_CMD			0x10	/* Crypto Engine Command Register */
2462f58b16SNeal Liu 
2562f58b16SNeal Liu /* G5 */
2662f58b16SNeal Liu #define ASPEED_HACE_TAG			0x18	/* HACE Tag Register */
2762f58b16SNeal Liu /* G6 */
2862f58b16SNeal Liu #define ASPEED_HACE_GCM_ADD_LEN		0x14	/* Crypto AES-GCM Additional Data Length Register */
2962f58b16SNeal Liu #define ASPEED_HACE_GCM_TAG_BASE_ADDR	0x18	/* Crypto AES-GCM Tag Write Buff Base Address Reg */
30108713a7SNeal Liu 
31108713a7SNeal Liu #define ASPEED_HACE_STS			0x1C	/* HACE Status Register */
3262f58b16SNeal Liu 
33108713a7SNeal Liu #define ASPEED_HACE_HASH_SRC		0x20	/* Hash Data Source Base Address Register */
34108713a7SNeal Liu #define ASPEED_HACE_HASH_DIGEST_BUFF	0x24	/* Hash Digest Write Buffer Base Address Register */
35108713a7SNeal Liu #define ASPEED_HACE_HASH_KEY_BUFF	0x28	/* Hash HMAC Key Buffer Base Address Register */
36108713a7SNeal Liu #define ASPEED_HACE_HASH_DATA_LEN	0x2C	/* Hash Data Length Register */
37108713a7SNeal Liu #define ASPEED_HACE_HASH_CMD		0x30	/* Hash Engine Command Register */
38108713a7SNeal Liu 
3962f58b16SNeal Liu /* crypto cmd */
4062f58b16SNeal Liu #define  HACE_CMD_SINGLE_DES		0
4162f58b16SNeal Liu #define  HACE_CMD_TRIPLE_DES		BIT(17)
4262f58b16SNeal Liu #define  HACE_CMD_AES_SELECT		0
4362f58b16SNeal Liu #define  HACE_CMD_DES_SELECT		BIT(16)
4462f58b16SNeal Liu #define  HACE_CMD_ISR_EN		BIT(12)
4562f58b16SNeal Liu #define  HACE_CMD_CONTEXT_SAVE_ENABLE	(0)
4662f58b16SNeal Liu #define  HACE_CMD_CONTEXT_SAVE_DISABLE	BIT(9)
4762f58b16SNeal Liu #define  HACE_CMD_AES			(0)
4862f58b16SNeal Liu #define  HACE_CMD_DES			(0)
4962f58b16SNeal Liu #define  HACE_CMD_RC4			BIT(8)
5062f58b16SNeal Liu #define  HACE_CMD_DECRYPT		(0)
5162f58b16SNeal Liu #define  HACE_CMD_ENCRYPT		BIT(7)
5262f58b16SNeal Liu 
5362f58b16SNeal Liu #define  HACE_CMD_ECB			(0x0 << 4)
5462f58b16SNeal Liu #define  HACE_CMD_CBC			(0x1 << 4)
5562f58b16SNeal Liu #define  HACE_CMD_CFB			(0x2 << 4)
5662f58b16SNeal Liu #define  HACE_CMD_OFB			(0x3 << 4)
5762f58b16SNeal Liu #define  HACE_CMD_CTR			(0x4 << 4)
5862f58b16SNeal Liu #define  HACE_CMD_OP_MODE_MASK		(0x7 << 4)
5962f58b16SNeal Liu 
6062f58b16SNeal Liu #define  HACE_CMD_AES128		(0x0 << 2)
6162f58b16SNeal Liu #define  HACE_CMD_AES192		(0x1 << 2)
6262f58b16SNeal Liu #define  HACE_CMD_AES256		(0x2 << 2)
6362f58b16SNeal Liu #define  HACE_CMD_OP_CASCADE		(0x3)
6462f58b16SNeal Liu #define  HACE_CMD_OP_INDEPENDENT	(0x1)
6562f58b16SNeal Liu 
6662f58b16SNeal Liu /* G5 */
6762f58b16SNeal Liu #define  HACE_CMD_RI_WO_DATA_ENABLE	(0)
6862f58b16SNeal Liu #define  HACE_CMD_RI_WO_DATA_DISABLE	BIT(11)
6962f58b16SNeal Liu #define  HACE_CMD_CONTEXT_LOAD_ENABLE	(0)
7062f58b16SNeal Liu #define  HACE_CMD_CONTEXT_LOAD_DISABLE	BIT(10)
7162f58b16SNeal Liu /* G6 */
7262f58b16SNeal Liu #define  HACE_CMD_AES_KEY_FROM_OTP	BIT(24)
7362f58b16SNeal Liu #define  HACE_CMD_GHASH_TAG_XOR_EN	BIT(23)
7462f58b16SNeal Liu #define  HACE_CMD_GHASH_PAD_LEN_INV	BIT(22)
7562f58b16SNeal Liu #define  HACE_CMD_GCM_TAG_ADDR_SEL	BIT(21)
7662f58b16SNeal Liu #define  HACE_CMD_MBUS_REQ_SYNC_EN	BIT(20)
7762f58b16SNeal Liu #define  HACE_CMD_DES_SG_CTRL		BIT(19)
7862f58b16SNeal Liu #define  HACE_CMD_SRC_SG_CTRL		BIT(18)
7962f58b16SNeal Liu #define  HACE_CMD_CTR_IV_AES_96		(0x1 << 14)
8062f58b16SNeal Liu #define  HACE_CMD_CTR_IV_DES_32		(0x1 << 14)
8162f58b16SNeal Liu #define  HACE_CMD_CTR_IV_AES_64		(0x2 << 14)
8262f58b16SNeal Liu #define  HACE_CMD_CTR_IV_AES_32		(0x3 << 14)
8362f58b16SNeal Liu #define  HACE_CMD_AES_KEY_HW_EXP	BIT(13)
8462f58b16SNeal Liu #define  HACE_CMD_GCM			(0x5 << 4)
8562f58b16SNeal Liu 
86108713a7SNeal Liu /* interrupt status reg */
8762f58b16SNeal Liu #define  HACE_CRYPTO_ISR		BIT(12)
88108713a7SNeal Liu #define  HACE_HASH_ISR			BIT(9)
89108713a7SNeal Liu #define  HACE_HASH_BUSY			BIT(0)
90108713a7SNeal Liu 
91108713a7SNeal Liu /* hash cmd reg */
92108713a7SNeal Liu #define  HASH_CMD_MBUS_REQ_SYNC_EN	BIT(20)
93108713a7SNeal Liu #define  HASH_CMD_HASH_SRC_SG_CTRL	BIT(18)
94108713a7SNeal Liu #define  HASH_CMD_SHA512_224		(0x3 << 10)
95108713a7SNeal Liu #define  HASH_CMD_SHA512_256		(0x2 << 10)
96108713a7SNeal Liu #define  HASH_CMD_SHA384		(0x1 << 10)
97108713a7SNeal Liu #define  HASH_CMD_SHA512		(0)
98108713a7SNeal Liu #define  HASH_CMD_INT_ENABLE		BIT(9)
99108713a7SNeal Liu #define  HASH_CMD_HMAC			(0x1 << 7)
100108713a7SNeal Liu #define  HASH_CMD_ACC_MODE		(0x2 << 7)
101108713a7SNeal Liu #define  HASH_CMD_HMAC_KEY		(0x3 << 7)
102108713a7SNeal Liu #define  HASH_CMD_SHA1			(0x2 << 4)
103108713a7SNeal Liu #define  HASH_CMD_SHA224		(0x4 << 4)
104108713a7SNeal Liu #define  HASH_CMD_SHA256		(0x5 << 4)
105108713a7SNeal Liu #define  HASH_CMD_SHA512_SER		(0x6 << 4)
106108713a7SNeal Liu #define  HASH_CMD_SHA_SWAP		(0x2 << 2)
107108713a7SNeal Liu 
108108713a7SNeal Liu #define HASH_SG_LAST_LIST		BIT(31)
109108713a7SNeal Liu 
110108713a7SNeal Liu #define CRYPTO_FLAGS_BUSY		BIT(1)
111108713a7SNeal Liu 
112108713a7SNeal Liu #define SHA_OP_UPDATE			1
113108713a7SNeal Liu #define SHA_OP_FINAL			2
114108713a7SNeal Liu 
115108713a7SNeal Liu #define SHA_FLAGS_SHA1			BIT(0)
116108713a7SNeal Liu #define SHA_FLAGS_SHA224		BIT(1)
117108713a7SNeal Liu #define SHA_FLAGS_SHA256		BIT(2)
118108713a7SNeal Liu #define SHA_FLAGS_SHA384		BIT(3)
119108713a7SNeal Liu #define SHA_FLAGS_SHA512		BIT(4)
120108713a7SNeal Liu #define SHA_FLAGS_SHA512_224		BIT(5)
121108713a7SNeal Liu #define SHA_FLAGS_SHA512_256		BIT(6)
122108713a7SNeal Liu #define SHA_FLAGS_HMAC			BIT(8)
123108713a7SNeal Liu #define SHA_FLAGS_FINUP			BIT(9)
124108713a7SNeal Liu #define SHA_FLAGS_MASK			(0xff)
125108713a7SNeal Liu 
126108713a7SNeal Liu #define ASPEED_CRYPTO_SRC_DMA_BUF_LEN	0xa000
127108713a7SNeal Liu #define ASPEED_CRYPTO_DST_DMA_BUF_LEN	0xa000
128108713a7SNeal Liu #define ASPEED_CRYPTO_GCM_TAG_OFFSET	0x9ff0
129108713a7SNeal Liu #define ASPEED_HASH_SRC_DMA_BUF_LEN	0xa000
130108713a7SNeal Liu #define ASPEED_HASH_QUEUE_LENGTH	50
131108713a7SNeal Liu 
13262f58b16SNeal Liu #define HACE_CMD_IV_REQUIRE		(HACE_CMD_CBC | HACE_CMD_CFB | \
13362f58b16SNeal Liu 					 HACE_CMD_OFB | HACE_CMD_CTR)
13462f58b16SNeal Liu 
135108713a7SNeal Liu struct aspeed_hace_dev;
136*304506f2SHerbert Xu struct scatterlist;
137108713a7SNeal Liu 
138108713a7SNeal Liu typedef int (*aspeed_hace_fn_t)(struct aspeed_hace_dev *);
139108713a7SNeal Liu 
140108713a7SNeal Liu struct aspeed_sg_list {
141108713a7SNeal Liu 	__le32 len;
142108713a7SNeal Liu 	__le32 phy_addr;
143108713a7SNeal Liu };
144108713a7SNeal Liu 
145108713a7SNeal Liu struct aspeed_engine_hash {
146108713a7SNeal Liu 	struct tasklet_struct		done_task;
147108713a7SNeal Liu 	unsigned long			flags;
148108713a7SNeal Liu 	struct ahash_request		*req;
149108713a7SNeal Liu 
150108713a7SNeal Liu 	/* input buffer */
151108713a7SNeal Liu 	void				*ahash_src_addr;
152108713a7SNeal Liu 	dma_addr_t			ahash_src_dma_addr;
153108713a7SNeal Liu 
154108713a7SNeal Liu 	dma_addr_t			src_dma;
155108713a7SNeal Liu 	dma_addr_t			digest_dma;
156108713a7SNeal Liu 
157108713a7SNeal Liu 	size_t				src_length;
158108713a7SNeal Liu 
159108713a7SNeal Liu 	/* callback func */
160108713a7SNeal Liu 	aspeed_hace_fn_t		resume;
161108713a7SNeal Liu 	aspeed_hace_fn_t		dma_prepare;
162108713a7SNeal Liu };
163108713a7SNeal Liu 
164108713a7SNeal Liu struct aspeed_sha_hmac_ctx {
165108713a7SNeal Liu 	struct crypto_shash *shash;
166108713a7SNeal Liu 	u8 ipad[SHA512_BLOCK_SIZE];
167108713a7SNeal Liu 	u8 opad[SHA512_BLOCK_SIZE];
168108713a7SNeal Liu };
169108713a7SNeal Liu 
170108713a7SNeal Liu struct aspeed_sham_ctx {
171108713a7SNeal Liu 	struct aspeed_hace_dev		*hace_dev;
172108713a7SNeal Liu 	unsigned long			flags;	/* hmac flag */
173108713a7SNeal Liu 
174f104b216SGustavo A. R. Silva 	struct aspeed_sha_hmac_ctx	base[];
175108713a7SNeal Liu };
176108713a7SNeal Liu 
177108713a7SNeal Liu struct aspeed_sham_reqctx {
178108713a7SNeal Liu 	unsigned long		flags;		/* final update flag should no use*/
179108713a7SNeal Liu 	unsigned long		op;		/* final or update */
180108713a7SNeal Liu 	u32			cmd;		/* trigger cmd */
181108713a7SNeal Liu 
182108713a7SNeal Liu 	/* walk state */
183108713a7SNeal Liu 	struct scatterlist	*src_sg;
184108713a7SNeal Liu 	int			src_nents;
185108713a7SNeal Liu 	unsigned int		offset;		/* offset in current sg */
186108713a7SNeal Liu 	unsigned int		total;		/* per update length */
187108713a7SNeal Liu 
188108713a7SNeal Liu 	size_t			digsize;
189108713a7SNeal Liu 	size_t			block_size;
190108713a7SNeal Liu 	size_t			ivsize;
191108713a7SNeal Liu 	const __be32		*sha_iv;
192108713a7SNeal Liu 
193108713a7SNeal Liu 	/* remain data buffer */
194108713a7SNeal Liu 	u8			buffer[SHA512_BLOCK_SIZE * 2];
195108713a7SNeal Liu 	dma_addr_t		buffer_dma_addr;
196108713a7SNeal Liu 	size_t			bufcnt;		/* buffer counter */
197108713a7SNeal Liu 
198108713a7SNeal Liu 	/* output buffer */
199108713a7SNeal Liu 	u8			digest[SHA512_DIGEST_SIZE] __aligned(64);
200108713a7SNeal Liu 	dma_addr_t		digest_dma_addr;
201108713a7SNeal Liu 	u64			digcnt[2];
202108713a7SNeal Liu };
203108713a7SNeal Liu 
20462f58b16SNeal Liu struct aspeed_engine_crypto {
20562f58b16SNeal Liu 	struct tasklet_struct		done_task;
20662f58b16SNeal Liu 	unsigned long			flags;
20762f58b16SNeal Liu 	struct skcipher_request		*req;
20862f58b16SNeal Liu 
20962f58b16SNeal Liu 	/* context buffer */
21062f58b16SNeal Liu 	void				*cipher_ctx;
21162f58b16SNeal Liu 	dma_addr_t			cipher_ctx_dma;
21262f58b16SNeal Liu 
21362f58b16SNeal Liu 	/* input buffer, could be single/scatter-gather lists */
21462f58b16SNeal Liu 	void				*cipher_addr;
21562f58b16SNeal Liu 	dma_addr_t			cipher_dma_addr;
21662f58b16SNeal Liu 
21762f58b16SNeal Liu 	/* output buffer, only used in scatter-gather lists */
21862f58b16SNeal Liu 	void				*dst_sg_addr;
21962f58b16SNeal Liu 	dma_addr_t			dst_sg_dma_addr;
22062f58b16SNeal Liu 
22162f58b16SNeal Liu 	/* callback func */
22262f58b16SNeal Liu 	aspeed_hace_fn_t		resume;
22362f58b16SNeal Liu };
22462f58b16SNeal Liu 
22562f58b16SNeal Liu struct aspeed_cipher_ctx {
22662f58b16SNeal Liu 	struct aspeed_hace_dev		*hace_dev;
22762f58b16SNeal Liu 	int				key_len;
22862f58b16SNeal Liu 	u8				key[AES_MAX_KEYLENGTH];
22962f58b16SNeal Liu 
23062f58b16SNeal Liu 	/* callback func */
23162f58b16SNeal Liu 	aspeed_hace_fn_t		start;
23262f58b16SNeal Liu 
23362f58b16SNeal Liu 	struct crypto_skcipher          *fallback_tfm;
23462f58b16SNeal Liu };
23562f58b16SNeal Liu 
23662f58b16SNeal Liu struct aspeed_cipher_reqctx {
23762f58b16SNeal Liu 	int enc_cmd;
23862f58b16SNeal Liu 	int src_nents;
23962f58b16SNeal Liu 	int dst_nents;
24062f58b16SNeal Liu 
24162f58b16SNeal Liu 	struct skcipher_request         fallback_req;   /* keep at the end */
24262f58b16SNeal Liu };
24362f58b16SNeal Liu 
244108713a7SNeal Liu struct aspeed_hace_dev {
245108713a7SNeal Liu 	void __iomem			*regs;
246108713a7SNeal Liu 	struct device			*dev;
247108713a7SNeal Liu 	int				irq;
248108713a7SNeal Liu 	struct clk			*clk;
249108713a7SNeal Liu 	unsigned long			version;
250108713a7SNeal Liu 
251108713a7SNeal Liu 	struct crypto_engine		*crypt_engine_hash;
25262f58b16SNeal Liu 	struct crypto_engine		*crypt_engine_crypto;
253108713a7SNeal Liu 
254108713a7SNeal Liu 	struct aspeed_engine_hash	hash_engine;
25562f58b16SNeal Liu 	struct aspeed_engine_crypto	crypto_engine;
256108713a7SNeal Liu };
257108713a7SNeal Liu 
258108713a7SNeal Liu struct aspeed_hace_alg {
259108713a7SNeal Liu 	struct aspeed_hace_dev		*hace_dev;
260108713a7SNeal Liu 
261108713a7SNeal Liu 	const char			*alg_base;
262108713a7SNeal Liu 
263108713a7SNeal Liu 	union {
264*304506f2SHerbert Xu 		struct skcipher_engine_alg skcipher;
265*304506f2SHerbert Xu 		struct ahash_engine_alg ahash;
266108713a7SNeal Liu 	} alg;
267108713a7SNeal Liu };
268108713a7SNeal Liu 
269108713a7SNeal Liu enum aspeed_version {
270108713a7SNeal Liu 	AST2500_VERSION = 5,
271108713a7SNeal Liu 	AST2600_VERSION
272108713a7SNeal Liu };
273108713a7SNeal Liu 
274108713a7SNeal Liu #define ast_hace_write(hace, val, offset)	\
275108713a7SNeal Liu 	writel((val), (hace)->regs + (offset))
276108713a7SNeal Liu #define ast_hace_read(hace, offset)		\
277108713a7SNeal Liu 	readl((hace)->regs + (offset))
278108713a7SNeal Liu 
279108713a7SNeal Liu void aspeed_register_hace_hash_algs(struct aspeed_hace_dev *hace_dev);
280108713a7SNeal Liu void aspeed_unregister_hace_hash_algs(struct aspeed_hace_dev *hace_dev);
28162f58b16SNeal Liu void aspeed_register_hace_crypto_algs(struct aspeed_hace_dev *hace_dev);
28262f58b16SNeal Liu void aspeed_unregister_hace_crypto_algs(struct aspeed_hace_dev *hace_dev);
283108713a7SNeal Liu 
284108713a7SNeal Liu #endif
285