xref: /OK3568_Linux_fs/kernel/drivers/mmc/host/cqhci.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /* Copyright (c) 2015, The Linux Foundation. All rights reserved.
3*4882a593Smuzhiyun  */
4*4882a593Smuzhiyun #ifndef LINUX_MMC_CQHCI_H
5*4882a593Smuzhiyun #define LINUX_MMC_CQHCI_H
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/compiler.h>
8*4882a593Smuzhiyun #include <linux/bitops.h>
9*4882a593Smuzhiyun #include <linux/spinlock_types.h>
10*4882a593Smuzhiyun #include <linux/types.h>
11*4882a593Smuzhiyun #include <linux/completion.h>
12*4882a593Smuzhiyun #include <linux/wait.h>
13*4882a593Smuzhiyun #include <linux/irqreturn.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /* registers */
17*4882a593Smuzhiyun /* version */
18*4882a593Smuzhiyun #define CQHCI_VER			0x00
19*4882a593Smuzhiyun #define CQHCI_VER_MAJOR(x)		(((x) & GENMASK(11, 8)) >> 8)
20*4882a593Smuzhiyun #define CQHCI_VER_MINOR1(x)		(((x) & GENMASK(7, 4)) >> 4)
21*4882a593Smuzhiyun #define CQHCI_VER_MINOR2(x)		((x) & GENMASK(3, 0))
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun /* capabilities */
24*4882a593Smuzhiyun #define CQHCI_CAP			0x04
25*4882a593Smuzhiyun #define CQHCI_CAP_CS			0x10000000 /* Crypto Support */
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun /* configuration */
28*4882a593Smuzhiyun #define CQHCI_CFG			0x08
29*4882a593Smuzhiyun #define CQHCI_DCMD			0x00001000
30*4882a593Smuzhiyun #define CQHCI_TASK_DESC_SZ		0x00000100
31*4882a593Smuzhiyun #define CQHCI_CRYPTO_GENERAL_ENABLE	0x00000002
32*4882a593Smuzhiyun #define CQHCI_ENABLE			0x00000001
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /* control */
35*4882a593Smuzhiyun #define CQHCI_CTL			0x0C
36*4882a593Smuzhiyun #define CQHCI_CLEAR_ALL_TASKS		0x00000100
37*4882a593Smuzhiyun #define CQHCI_HALT			0x00000001
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* interrupt status */
40*4882a593Smuzhiyun #define CQHCI_IS			0x10
41*4882a593Smuzhiyun #define CQHCI_IS_HAC			BIT(0)
42*4882a593Smuzhiyun #define CQHCI_IS_TCC			BIT(1)
43*4882a593Smuzhiyun #define CQHCI_IS_RED			BIT(2)
44*4882a593Smuzhiyun #define CQHCI_IS_TCL			BIT(3)
45*4882a593Smuzhiyun #define CQHCI_IS_GCE			BIT(4) /* General Crypto Error */
46*4882a593Smuzhiyun #define CQHCI_IS_ICCE			BIT(5) /* Invalid Crypto Config Error */
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define CQHCI_IS_MASK (CQHCI_IS_TCC | CQHCI_IS_RED | \
49*4882a593Smuzhiyun 		       CQHCI_IS_GCE | CQHCI_IS_ICCE)
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* interrupt status enable */
52*4882a593Smuzhiyun #define CQHCI_ISTE			0x14
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* interrupt signal enable */
55*4882a593Smuzhiyun #define CQHCI_ISGE			0x18
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* interrupt coalescing */
58*4882a593Smuzhiyun #define CQHCI_IC			0x1C
59*4882a593Smuzhiyun #define CQHCI_IC_ENABLE			BIT(31)
60*4882a593Smuzhiyun #define CQHCI_IC_RESET			BIT(16)
61*4882a593Smuzhiyun #define CQHCI_IC_ICCTHWEN		BIT(15)
62*4882a593Smuzhiyun #define CQHCI_IC_ICCTH(x)		(((x) & 0x1F) << 8)
63*4882a593Smuzhiyun #define CQHCI_IC_ICTOVALWEN		BIT(7)
64*4882a593Smuzhiyun #define CQHCI_IC_ICTOVAL(x)		((x) & 0x7F)
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /* task list base address */
67*4882a593Smuzhiyun #define CQHCI_TDLBA			0x20
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* task list base address upper */
70*4882a593Smuzhiyun #define CQHCI_TDLBAU			0x24
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /* door-bell */
73*4882a593Smuzhiyun #define CQHCI_TDBR			0x28
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun /* task completion notification */
76*4882a593Smuzhiyun #define CQHCI_TCN			0x2C
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* device queue status */
79*4882a593Smuzhiyun #define CQHCI_DQS			0x30
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /* device pending tasks */
82*4882a593Smuzhiyun #define CQHCI_DPT			0x34
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /* task clear */
85*4882a593Smuzhiyun #define CQHCI_TCLR			0x38
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun /* task descriptor processing error */
88*4882a593Smuzhiyun #define CQHCI_TDPE			0x3c
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /* send status config 1 */
91*4882a593Smuzhiyun #define CQHCI_SSC1			0x40
92*4882a593Smuzhiyun #define CQHCI_SSC1_CBC_MASK		GENMASK(19, 16)
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /* send status config 2 */
95*4882a593Smuzhiyun #define CQHCI_SSC2			0x44
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* response for dcmd */
98*4882a593Smuzhiyun #define CQHCI_CRDCT			0x48
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /* response mode error mask */
101*4882a593Smuzhiyun #define CQHCI_RMEM			0x50
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /* task error info */
104*4882a593Smuzhiyun #define CQHCI_TERRI			0x54
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun #define CQHCI_TERRI_C_INDEX(x)		((x) & GENMASK(5, 0))
107*4882a593Smuzhiyun #define CQHCI_TERRI_C_TASK(x)		(((x) & GENMASK(12, 8)) >> 8)
108*4882a593Smuzhiyun #define CQHCI_TERRI_C_VALID(x)		((x) & BIT(15))
109*4882a593Smuzhiyun #define CQHCI_TERRI_D_INDEX(x)		(((x) & GENMASK(21, 16)) >> 16)
110*4882a593Smuzhiyun #define CQHCI_TERRI_D_TASK(x)		(((x) & GENMASK(28, 24)) >> 24)
111*4882a593Smuzhiyun #define CQHCI_TERRI_D_VALID(x)		((x) & BIT(31))
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun /* command response index */
114*4882a593Smuzhiyun #define CQHCI_CRI			0x58
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun /* command response argument */
117*4882a593Smuzhiyun #define CQHCI_CRA			0x5C
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun /* crypto capabilities */
120*4882a593Smuzhiyun #define CQHCI_CCAP			0x100
121*4882a593Smuzhiyun #define CQHCI_CRYPTOCAP			0x104
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun #define CQHCI_INT_ALL			0xF
124*4882a593Smuzhiyun #define CQHCI_IC_DEFAULT_ICCTH		31
125*4882a593Smuzhiyun #define CQHCI_IC_DEFAULT_ICTOVAL	1
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /* attribute fields */
128*4882a593Smuzhiyun #define CQHCI_VALID(x)			(((x) & 1) << 0)
129*4882a593Smuzhiyun #define CQHCI_END(x)			(((x) & 1) << 1)
130*4882a593Smuzhiyun #define CQHCI_INT(x)			(((x) & 1) << 2)
131*4882a593Smuzhiyun #define CQHCI_ACT(x)			(((x) & 0x7) << 3)
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun /* data command task descriptor fields */
134*4882a593Smuzhiyun #define CQHCI_FORCED_PROG(x)		(((x) & 1) << 6)
135*4882a593Smuzhiyun #define CQHCI_CONTEXT(x)		(((x) & 0xF) << 7)
136*4882a593Smuzhiyun #define CQHCI_DATA_TAG(x)		(((x) & 1) << 11)
137*4882a593Smuzhiyun #define CQHCI_DATA_DIR(x)		(((x) & 1) << 12)
138*4882a593Smuzhiyun #define CQHCI_PRIORITY(x)		(((x) & 1) << 13)
139*4882a593Smuzhiyun #define CQHCI_QBAR(x)			(((x) & 1) << 14)
140*4882a593Smuzhiyun #define CQHCI_REL_WRITE(x)		(((x) & 1) << 15)
141*4882a593Smuzhiyun #define CQHCI_BLK_COUNT(x)		(((x) & 0xFFFF) << 16)
142*4882a593Smuzhiyun #define CQHCI_BLK_ADDR(x)		(((x) & 0xFFFFFFFF) << 32)
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /* direct command task descriptor fields */
145*4882a593Smuzhiyun #define CQHCI_CMD_INDEX(x)		(((x) & 0x3F) << 16)
146*4882a593Smuzhiyun #define CQHCI_CMD_TIMING(x)		(((x) & 1) << 22)
147*4882a593Smuzhiyun #define CQHCI_RESP_TYPE(x)		(((x) & 0x3) << 23)
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /* crypto task descriptor fields (for bits 64-127 of task descriptor) */
150*4882a593Smuzhiyun #define CQHCI_CRYPTO_ENABLE_BIT		(1ULL << 47)
151*4882a593Smuzhiyun #define CQHCI_CRYPTO_KEYSLOT(x)		((u64)(x) << 32)
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /* transfer descriptor fields */
154*4882a593Smuzhiyun #define CQHCI_DAT_LENGTH(x)		(((x) & 0xFFFF) << 16)
155*4882a593Smuzhiyun #define CQHCI_DAT_ADDR_LO(x)		(((x) & 0xFFFFFFFF) << 32)
156*4882a593Smuzhiyun #define CQHCI_DAT_ADDR_HI(x)		(((x) & 0xFFFFFFFF) << 0)
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /* CCAP - Crypto Capability 100h */
159*4882a593Smuzhiyun union cqhci_crypto_capabilities {
160*4882a593Smuzhiyun 	__le32 reg_val;
161*4882a593Smuzhiyun 	struct {
162*4882a593Smuzhiyun 		u8 num_crypto_cap;
163*4882a593Smuzhiyun 		u8 config_count;
164*4882a593Smuzhiyun 		u8 reserved;
165*4882a593Smuzhiyun 		u8 config_array_ptr;
166*4882a593Smuzhiyun 	};
167*4882a593Smuzhiyun };
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun enum cqhci_crypto_key_size {
170*4882a593Smuzhiyun 	CQHCI_CRYPTO_KEY_SIZE_INVALID	= 0,
171*4882a593Smuzhiyun 	CQHCI_CRYPTO_KEY_SIZE_128	= 1,
172*4882a593Smuzhiyun 	CQHCI_CRYPTO_KEY_SIZE_192	= 2,
173*4882a593Smuzhiyun 	CQHCI_CRYPTO_KEY_SIZE_256	= 3,
174*4882a593Smuzhiyun 	CQHCI_CRYPTO_KEY_SIZE_512	= 4,
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun enum cqhci_crypto_alg {
178*4882a593Smuzhiyun 	CQHCI_CRYPTO_ALG_AES_XTS		= 0,
179*4882a593Smuzhiyun 	CQHCI_CRYPTO_ALG_BITLOCKER_AES_CBC	= 1,
180*4882a593Smuzhiyun 	CQHCI_CRYPTO_ALG_AES_ECB		= 2,
181*4882a593Smuzhiyun 	CQHCI_CRYPTO_ALG_ESSIV_AES_CBC		= 3,
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /* x-CRYPTOCAP - Crypto Capability X */
185*4882a593Smuzhiyun union cqhci_crypto_cap_entry {
186*4882a593Smuzhiyun 	__le32 reg_val;
187*4882a593Smuzhiyun 	struct {
188*4882a593Smuzhiyun 		u8 algorithm_id;
189*4882a593Smuzhiyun 		u8 sdus_mask; /* Supported data unit size mask */
190*4882a593Smuzhiyun 		u8 key_size;
191*4882a593Smuzhiyun 		u8 reserved;
192*4882a593Smuzhiyun 	};
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #define CQHCI_CRYPTO_CONFIGURATION_ENABLE (1 << 7)
196*4882a593Smuzhiyun #define CQHCI_CRYPTO_KEY_MAX_SIZE 64
197*4882a593Smuzhiyun /* x-CRYPTOCFG - Crypto Configuration X */
198*4882a593Smuzhiyun union cqhci_crypto_cfg_entry {
199*4882a593Smuzhiyun 	__le32 reg_val[32];
200*4882a593Smuzhiyun 	struct {
201*4882a593Smuzhiyun 		u8 crypto_key[CQHCI_CRYPTO_KEY_MAX_SIZE];
202*4882a593Smuzhiyun 		u8 data_unit_size;
203*4882a593Smuzhiyun 		u8 crypto_cap_idx;
204*4882a593Smuzhiyun 		u8 reserved_1;
205*4882a593Smuzhiyun 		u8 config_enable;
206*4882a593Smuzhiyun 		u8 reserved_multi_host;
207*4882a593Smuzhiyun 		u8 reserved_2;
208*4882a593Smuzhiyun 		u8 vsb[2];
209*4882a593Smuzhiyun 		u8 reserved_3[56];
210*4882a593Smuzhiyun 	};
211*4882a593Smuzhiyun };
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun struct cqhci_host_ops;
214*4882a593Smuzhiyun struct mmc_host;
215*4882a593Smuzhiyun struct mmc_request;
216*4882a593Smuzhiyun struct cqhci_slot;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun struct cqhci_host {
219*4882a593Smuzhiyun 	const struct cqhci_host_ops *ops;
220*4882a593Smuzhiyun 	void __iomem *mmio;
221*4882a593Smuzhiyun 	struct mmc_host *mmc;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	spinlock_t lock;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	/* relative card address of device */
226*4882a593Smuzhiyun 	unsigned int rca;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	/* 64 bit DMA */
229*4882a593Smuzhiyun 	bool dma64;
230*4882a593Smuzhiyun 	int num_slots;
231*4882a593Smuzhiyun 	int qcnt;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	u32 dcmd_slot;
234*4882a593Smuzhiyun 	u32 caps;
235*4882a593Smuzhiyun #define CQHCI_TASK_DESC_SZ_128		0x1
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	u32 quirks;
238*4882a593Smuzhiyun #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ	0x1
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	bool enabled;
241*4882a593Smuzhiyun 	bool halted;
242*4882a593Smuzhiyun 	bool init_done;
243*4882a593Smuzhiyun 	bool activated;
244*4882a593Smuzhiyun 	bool waiting_for_idle;
245*4882a593Smuzhiyun 	bool recovery_halt;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	size_t desc_size;
248*4882a593Smuzhiyun 	size_t data_size;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	u8 *desc_base;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	/* total descriptor size */
253*4882a593Smuzhiyun 	u8 slot_sz;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	/* 64/128 bit depends on CQHCI_CFG */
256*4882a593Smuzhiyun 	u8 task_desc_len;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	/* 64 bit on 32-bit arch, 128 bit on 64-bit */
259*4882a593Smuzhiyun 	u8 link_desc_len;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	u8 *trans_desc_base;
262*4882a593Smuzhiyun 	/* same length as transfer descriptor */
263*4882a593Smuzhiyun 	u8 trans_desc_len;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	dma_addr_t desc_dma_base;
266*4882a593Smuzhiyun 	dma_addr_t trans_desc_dma_base;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	struct completion halt_comp;
269*4882a593Smuzhiyun 	wait_queue_head_t wait_queue;
270*4882a593Smuzhiyun 	struct cqhci_slot *slot;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun #ifdef CONFIG_MMC_CRYPTO
273*4882a593Smuzhiyun 	union cqhci_crypto_capabilities crypto_capabilities;
274*4882a593Smuzhiyun 	union cqhci_crypto_cap_entry *crypto_cap_array;
275*4882a593Smuzhiyun 	u32 crypto_cfg_register;
276*4882a593Smuzhiyun #endif
277*4882a593Smuzhiyun };
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun struct cqhci_host_ops {
280*4882a593Smuzhiyun 	void (*dumpregs)(struct mmc_host *mmc);
281*4882a593Smuzhiyun 	void (*write_l)(struct cqhci_host *host, u32 val, int reg);
282*4882a593Smuzhiyun 	u32 (*read_l)(struct cqhci_host *host, int reg);
283*4882a593Smuzhiyun 	void (*enable)(struct mmc_host *mmc);
284*4882a593Smuzhiyun 	void (*disable)(struct mmc_host *mmc, bool recovery);
285*4882a593Smuzhiyun 	void (*update_dcmd_desc)(struct mmc_host *mmc, struct mmc_request *mrq,
286*4882a593Smuzhiyun 				 u64 *data);
287*4882a593Smuzhiyun 	void (*pre_enable)(struct mmc_host *mmc);
288*4882a593Smuzhiyun 	void (*post_disable)(struct mmc_host *mmc);
289*4882a593Smuzhiyun #ifdef CONFIG_MMC_CRYPTO
290*4882a593Smuzhiyun 	int (*program_key)(struct cqhci_host *cq_host,
291*4882a593Smuzhiyun 			   const union cqhci_crypto_cfg_entry *cfg, int slot);
292*4882a593Smuzhiyun #endif
293*4882a593Smuzhiyun };
294*4882a593Smuzhiyun 
cqhci_writel(struct cqhci_host * host,u32 val,int reg)295*4882a593Smuzhiyun static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	if (unlikely(host->ops->write_l))
298*4882a593Smuzhiyun 		host->ops->write_l(host, val, reg);
299*4882a593Smuzhiyun 	else
300*4882a593Smuzhiyun 		writel_relaxed(val, host->mmio + reg);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
cqhci_readl(struct cqhci_host * host,int reg)303*4882a593Smuzhiyun static inline u32 cqhci_readl(struct cqhci_host *host, int reg)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun 	if (unlikely(host->ops->read_l))
306*4882a593Smuzhiyun 		return host->ops->read_l(host, reg);
307*4882a593Smuzhiyun 	else
308*4882a593Smuzhiyun 		return readl_relaxed(host->mmio + reg);
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun struct platform_device;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
314*4882a593Smuzhiyun 		      int data_error);
315*4882a593Smuzhiyun int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64);
316*4882a593Smuzhiyun struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev);
317*4882a593Smuzhiyun int cqhci_deactivate(struct mmc_host *mmc);
cqhci_suspend(struct mmc_host * mmc)318*4882a593Smuzhiyun static inline int cqhci_suspend(struct mmc_host *mmc)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun 	return cqhci_deactivate(mmc);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun int cqhci_resume(struct mmc_host *mmc);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun #endif
325