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