18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for EIP97 cryptographic accelerator.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2016 Ryder Lee <ryder.lee@mediatek.com>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __MTK_PLATFORM_H_
98c2ecf20Sopenharmony_ci#define __MTK_PLATFORM_H_
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <crypto/algapi.h>
128c2ecf20Sopenharmony_ci#include <crypto/internal/aead.h>
138c2ecf20Sopenharmony_ci#include <crypto/internal/hash.h>
148c2ecf20Sopenharmony_ci#include <crypto/scatterwalk.h>
158c2ecf20Sopenharmony_ci#include <crypto/skcipher.h>
168c2ecf20Sopenharmony_ci#include <linux/crypto.h>
178c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
188c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
198c2ecf20Sopenharmony_ci#include <linux/scatterlist.h>
208c2ecf20Sopenharmony_ci#include "mtk-regs.h"
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#define MTK_RDR_PROC_THRESH	BIT(0)
238c2ecf20Sopenharmony_ci#define MTK_RDR_PROC_MODE	BIT(23)
248c2ecf20Sopenharmony_ci#define MTK_CNT_RST		BIT(31)
258c2ecf20Sopenharmony_ci#define MTK_IRQ_RDR0		BIT(1)
268c2ecf20Sopenharmony_ci#define MTK_IRQ_RDR1		BIT(3)
278c2ecf20Sopenharmony_ci#define MTK_IRQ_RDR2		BIT(5)
288c2ecf20Sopenharmony_ci#define MTK_IRQ_RDR3		BIT(7)
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define SIZE_IN_WORDS(x)	((x) >> 2)
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/**
338c2ecf20Sopenharmony_ci * Ring 0/1 are used by AES encrypt and decrypt.
348c2ecf20Sopenharmony_ci * Ring 2/3 are used by SHA.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_cienum {
378c2ecf20Sopenharmony_ci	MTK_RING0,
388c2ecf20Sopenharmony_ci	MTK_RING1,
398c2ecf20Sopenharmony_ci	MTK_RING2,
408c2ecf20Sopenharmony_ci	MTK_RING3,
418c2ecf20Sopenharmony_ci	MTK_RING_MAX
428c2ecf20Sopenharmony_ci};
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#define MTK_REC_NUM		(MTK_RING_MAX / 2)
458c2ecf20Sopenharmony_ci#define MTK_IRQ_NUM		5
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/**
488c2ecf20Sopenharmony_ci * struct mtk_desc - DMA descriptor
498c2ecf20Sopenharmony_ci * @hdr:	the descriptor control header
508c2ecf20Sopenharmony_ci * @buf:	DMA address of input buffer segment
518c2ecf20Sopenharmony_ci * @ct:		DMA address of command token that control operation flow
528c2ecf20Sopenharmony_ci * @ct_hdr:	the command token control header
538c2ecf20Sopenharmony_ci * @tag:	the user-defined field
548c2ecf20Sopenharmony_ci * @tfm:	DMA address of transform state
558c2ecf20Sopenharmony_ci * @bound:	align descriptors offset boundary
568c2ecf20Sopenharmony_ci *
578c2ecf20Sopenharmony_ci * Structure passed to the crypto engine to describe where source
588c2ecf20Sopenharmony_ci * data needs to be fetched and how it needs to be processed.
598c2ecf20Sopenharmony_ci */
608c2ecf20Sopenharmony_cistruct mtk_desc {
618c2ecf20Sopenharmony_ci	__le32 hdr;
628c2ecf20Sopenharmony_ci	__le32 buf;
638c2ecf20Sopenharmony_ci	__le32 ct;
648c2ecf20Sopenharmony_ci	__le32 ct_hdr;
658c2ecf20Sopenharmony_ci	__le32 tag;
668c2ecf20Sopenharmony_ci	__le32 tfm;
678c2ecf20Sopenharmony_ci	__le32 bound[2];
688c2ecf20Sopenharmony_ci};
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define MTK_DESC_NUM		512
718c2ecf20Sopenharmony_ci#define MTK_DESC_OFF		SIZE_IN_WORDS(sizeof(struct mtk_desc))
728c2ecf20Sopenharmony_ci#define MTK_DESC_SZ		(MTK_DESC_OFF - 2)
738c2ecf20Sopenharmony_ci#define MTK_DESC_RING_SZ	((sizeof(struct mtk_desc) * MTK_DESC_NUM))
748c2ecf20Sopenharmony_ci#define MTK_DESC_CNT(x)		((MTK_DESC_OFF * (x)) << 2)
758c2ecf20Sopenharmony_ci#define MTK_DESC_LAST		cpu_to_le32(BIT(22))
768c2ecf20Sopenharmony_ci#define MTK_DESC_FIRST		cpu_to_le32(BIT(23))
778c2ecf20Sopenharmony_ci#define MTK_DESC_BUF_LEN(x)	cpu_to_le32(x)
788c2ecf20Sopenharmony_ci#define MTK_DESC_CT_LEN(x)	cpu_to_le32((x) << 24)
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/**
818c2ecf20Sopenharmony_ci * struct mtk_ring - Descriptor ring
828c2ecf20Sopenharmony_ci * @cmd_base:	pointer to command descriptor ring base
838c2ecf20Sopenharmony_ci * @cmd_next:	pointer to the next command descriptor
848c2ecf20Sopenharmony_ci * @cmd_dma:	DMA address of command descriptor ring
858c2ecf20Sopenharmony_ci * @res_base:	pointer to result descriptor ring base
868c2ecf20Sopenharmony_ci * @res_next:	pointer to the next result descriptor
878c2ecf20Sopenharmony_ci * @res_prev:	pointer to the previous result descriptor
888c2ecf20Sopenharmony_ci * @res_dma:	DMA address of result descriptor ring
898c2ecf20Sopenharmony_ci *
908c2ecf20Sopenharmony_ci * A descriptor ring is a circular buffer that is used to manage
918c2ecf20Sopenharmony_ci * one or more descriptors. There are two type of descriptor rings;
928c2ecf20Sopenharmony_ci * the command descriptor ring and result descriptor ring.
938c2ecf20Sopenharmony_ci */
948c2ecf20Sopenharmony_cistruct mtk_ring {
958c2ecf20Sopenharmony_ci	struct mtk_desc *cmd_base;
968c2ecf20Sopenharmony_ci	struct mtk_desc *cmd_next;
978c2ecf20Sopenharmony_ci	dma_addr_t cmd_dma;
988c2ecf20Sopenharmony_ci	struct mtk_desc *res_base;
998c2ecf20Sopenharmony_ci	struct mtk_desc *res_next;
1008c2ecf20Sopenharmony_ci	struct mtk_desc *res_prev;
1018c2ecf20Sopenharmony_ci	dma_addr_t res_dma;
1028c2ecf20Sopenharmony_ci};
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci/**
1058c2ecf20Sopenharmony_ci * struct mtk_aes_dma - Structure that holds sg list info
1068c2ecf20Sopenharmony_ci * @sg:		pointer to scatter-gather list
1078c2ecf20Sopenharmony_ci * @nents:	number of entries in the sg list
1088c2ecf20Sopenharmony_ci * @remainder:	remainder of sg list
1098c2ecf20Sopenharmony_ci * @sg_len:	number of entries in the sg mapped list
1108c2ecf20Sopenharmony_ci */
1118c2ecf20Sopenharmony_cistruct mtk_aes_dma {
1128c2ecf20Sopenharmony_ci	struct scatterlist *sg;
1138c2ecf20Sopenharmony_ci	int nents;
1148c2ecf20Sopenharmony_ci	u32 remainder;
1158c2ecf20Sopenharmony_ci	u32 sg_len;
1168c2ecf20Sopenharmony_ci};
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistruct mtk_aes_base_ctx;
1198c2ecf20Sopenharmony_cistruct mtk_aes_rec;
1208c2ecf20Sopenharmony_cistruct mtk_cryp;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_citypedef int (*mtk_aes_fn)(struct mtk_cryp *cryp, struct mtk_aes_rec *aes);
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci/**
1258c2ecf20Sopenharmony_ci * struct mtk_aes_rec - AES operation record
1268c2ecf20Sopenharmony_ci * @cryp:	pointer to Cryptographic device
1278c2ecf20Sopenharmony_ci * @queue:	crypto request queue
1288c2ecf20Sopenharmony_ci * @areq:	pointer to async request
1298c2ecf20Sopenharmony_ci * @done_task:	the tasklet is use in AES interrupt
1308c2ecf20Sopenharmony_ci * @queue_task:	the tasklet is used to dequeue request
1318c2ecf20Sopenharmony_ci * @ctx:	pointer to current context
1328c2ecf20Sopenharmony_ci * @src:	the structure that holds source sg list info
1338c2ecf20Sopenharmony_ci * @dst:	the structure that holds destination sg list info
1348c2ecf20Sopenharmony_ci * @aligned_sg:	the scatter list is use to alignment
1358c2ecf20Sopenharmony_ci * @real_dst:	pointer to the destination sg list
1368c2ecf20Sopenharmony_ci * @resume:	pointer to resume function
1378c2ecf20Sopenharmony_ci * @total:	request buffer length
1388c2ecf20Sopenharmony_ci * @buf:	pointer to page buffer
1398c2ecf20Sopenharmony_ci * @id:		the current use of ring
1408c2ecf20Sopenharmony_ci * @flags:	it's describing AES operation state
1418c2ecf20Sopenharmony_ci * @lock:	the async queue lock
1428c2ecf20Sopenharmony_ci *
1438c2ecf20Sopenharmony_ci * Structure used to record AES execution state.
1448c2ecf20Sopenharmony_ci */
1458c2ecf20Sopenharmony_cistruct mtk_aes_rec {
1468c2ecf20Sopenharmony_ci	struct mtk_cryp *cryp;
1478c2ecf20Sopenharmony_ci	struct crypto_queue queue;
1488c2ecf20Sopenharmony_ci	struct crypto_async_request *areq;
1498c2ecf20Sopenharmony_ci	struct tasklet_struct done_task;
1508c2ecf20Sopenharmony_ci	struct tasklet_struct queue_task;
1518c2ecf20Sopenharmony_ci	struct mtk_aes_base_ctx *ctx;
1528c2ecf20Sopenharmony_ci	struct mtk_aes_dma src;
1538c2ecf20Sopenharmony_ci	struct mtk_aes_dma dst;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	struct scatterlist aligned_sg;
1568c2ecf20Sopenharmony_ci	struct scatterlist *real_dst;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	mtk_aes_fn resume;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	size_t total;
1618c2ecf20Sopenharmony_ci	void *buf;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	u8 id;
1648c2ecf20Sopenharmony_ci	unsigned long flags;
1658c2ecf20Sopenharmony_ci	/* queue lock */
1668c2ecf20Sopenharmony_ci	spinlock_t lock;
1678c2ecf20Sopenharmony_ci};
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci/**
1708c2ecf20Sopenharmony_ci * struct mtk_sha_rec - SHA operation record
1718c2ecf20Sopenharmony_ci * @cryp:	pointer to Cryptographic device
1728c2ecf20Sopenharmony_ci * @queue:	crypto request queue
1738c2ecf20Sopenharmony_ci * @req:	pointer to ahash request
1748c2ecf20Sopenharmony_ci * @done_task:	the tasklet is use in SHA interrupt
1758c2ecf20Sopenharmony_ci * @queue_task:	the tasklet is used to dequeue request
1768c2ecf20Sopenharmony_ci * @id:		the current use of ring
1778c2ecf20Sopenharmony_ci * @flags:	it's describing SHA operation state
1788c2ecf20Sopenharmony_ci * @lock:	the async queue lock
1798c2ecf20Sopenharmony_ci *
1808c2ecf20Sopenharmony_ci * Structure used to record SHA execution state.
1818c2ecf20Sopenharmony_ci */
1828c2ecf20Sopenharmony_cistruct mtk_sha_rec {
1838c2ecf20Sopenharmony_ci	struct mtk_cryp *cryp;
1848c2ecf20Sopenharmony_ci	struct crypto_queue queue;
1858c2ecf20Sopenharmony_ci	struct ahash_request *req;
1868c2ecf20Sopenharmony_ci	struct tasklet_struct done_task;
1878c2ecf20Sopenharmony_ci	struct tasklet_struct queue_task;
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	u8 id;
1908c2ecf20Sopenharmony_ci	unsigned long flags;
1918c2ecf20Sopenharmony_ci	/* queue lock */
1928c2ecf20Sopenharmony_ci	spinlock_t lock;
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci/**
1968c2ecf20Sopenharmony_ci * struct mtk_cryp - Cryptographic device
1978c2ecf20Sopenharmony_ci * @base:	pointer to mapped register I/O base
1988c2ecf20Sopenharmony_ci * @dev:	pointer to device
1998c2ecf20Sopenharmony_ci * @clk_cryp:	pointer to crypto clock
2008c2ecf20Sopenharmony_ci * @irq:	global system and rings IRQ
2018c2ecf20Sopenharmony_ci * @ring:	pointer to descriptor rings
2028c2ecf20Sopenharmony_ci * @aes:	pointer to operation record of AES
2038c2ecf20Sopenharmony_ci * @sha:	pointer to operation record of SHA
2048c2ecf20Sopenharmony_ci * @aes_list:	device list of AES
2058c2ecf20Sopenharmony_ci * @sha_list:	device list of SHA
2068c2ecf20Sopenharmony_ci * @rec:	it's used to select SHA record for tfm
2078c2ecf20Sopenharmony_ci *
2088c2ecf20Sopenharmony_ci * Structure storing cryptographic device information.
2098c2ecf20Sopenharmony_ci */
2108c2ecf20Sopenharmony_cistruct mtk_cryp {
2118c2ecf20Sopenharmony_ci	void __iomem *base;
2128c2ecf20Sopenharmony_ci	struct device *dev;
2138c2ecf20Sopenharmony_ci	struct clk *clk_cryp;
2148c2ecf20Sopenharmony_ci	int irq[MTK_IRQ_NUM];
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	struct mtk_ring *ring[MTK_RING_MAX];
2178c2ecf20Sopenharmony_ci	struct mtk_aes_rec *aes[MTK_REC_NUM];
2188c2ecf20Sopenharmony_ci	struct mtk_sha_rec *sha[MTK_REC_NUM];
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	struct list_head aes_list;
2218c2ecf20Sopenharmony_ci	struct list_head sha_list;
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	bool rec;
2248c2ecf20Sopenharmony_ci};
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ciint mtk_cipher_alg_register(struct mtk_cryp *cryp);
2278c2ecf20Sopenharmony_civoid mtk_cipher_alg_release(struct mtk_cryp *cryp);
2288c2ecf20Sopenharmony_ciint mtk_hash_alg_register(struct mtk_cryp *cryp);
2298c2ecf20Sopenharmony_civoid mtk_hash_alg_release(struct mtk_cryp *cryp);
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci#endif /* __MTK_PLATFORM_H_ */
232