]>
Commit | Line | Data |
---|---|---|
97fb5e8d | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
a4080225 | 2 | /* Copyright (c) 2015, The Linux Foundation. All rights reserved. |
a4080225 VG |
3 | */ |
4 | #ifndef LINUX_MMC_CQHCI_H | |
5 | #define LINUX_MMC_CQHCI_H | |
6 | ||
7 | #include <linux/compiler.h> | |
8 | #include <linux/bitops.h> | |
9 | #include <linux/spinlock_types.h> | |
10 | #include <linux/types.h> | |
11 | #include <linux/completion.h> | |
12 | #include <linux/wait.h> | |
13 | #include <linux/irqreturn.h> | |
14 | #include <asm/io.h> | |
15 | ||
16 | /* registers */ | |
17 | /* version */ | |
18 | #define CQHCI_VER 0x00 | |
19 | #define CQHCI_VER_MAJOR(x) (((x) & GENMASK(11, 8)) >> 8) | |
20 | #define CQHCI_VER_MINOR1(x) (((x) & GENMASK(7, 4)) >> 4) | |
21 | #define CQHCI_VER_MINOR2(x) ((x) & GENMASK(3, 0)) | |
22 | ||
23 | /* capabilities */ | |
24 | #define CQHCI_CAP 0x04 | |
25 | /* configuration */ | |
26 | #define CQHCI_CFG 0x08 | |
27 | #define CQHCI_DCMD 0x00001000 | |
28 | #define CQHCI_TASK_DESC_SZ 0x00000100 | |
29 | #define CQHCI_ENABLE 0x00000001 | |
30 | ||
31 | /* control */ | |
32 | #define CQHCI_CTL 0x0C | |
33 | #define CQHCI_CLEAR_ALL_TASKS 0x00000100 | |
34 | #define CQHCI_HALT 0x00000001 | |
35 | ||
36 | /* interrupt status */ | |
37 | #define CQHCI_IS 0x10 | |
38 | #define CQHCI_IS_HAC BIT(0) | |
39 | #define CQHCI_IS_TCC BIT(1) | |
40 | #define CQHCI_IS_RED BIT(2) | |
41 | #define CQHCI_IS_TCL BIT(3) | |
42 | ||
43 | #define CQHCI_IS_MASK (CQHCI_IS_TCC | CQHCI_IS_RED) | |
44 | ||
45 | /* interrupt status enable */ | |
46 | #define CQHCI_ISTE 0x14 | |
47 | ||
48 | /* interrupt signal enable */ | |
49 | #define CQHCI_ISGE 0x18 | |
50 | ||
51 | /* interrupt coalescing */ | |
52 | #define CQHCI_IC 0x1C | |
53 | #define CQHCI_IC_ENABLE BIT(31) | |
54 | #define CQHCI_IC_RESET BIT(16) | |
55 | #define CQHCI_IC_ICCTHWEN BIT(15) | |
0562315b | 56 | #define CQHCI_IC_ICCTH(x) (((x) & 0x1F) << 8) |
a4080225 | 57 | #define CQHCI_IC_ICTOVALWEN BIT(7) |
0562315b | 58 | #define CQHCI_IC_ICTOVAL(x) ((x) & 0x7F) |
a4080225 VG |
59 | |
60 | /* task list base address */ | |
61 | #define CQHCI_TDLBA 0x20 | |
62 | ||
63 | /* task list base address upper */ | |
64 | #define CQHCI_TDLBAU 0x24 | |
65 | ||
66 | /* door-bell */ | |
67 | #define CQHCI_TDBR 0x28 | |
68 | ||
69 | /* task completion notification */ | |
70 | #define CQHCI_TCN 0x2C | |
71 | ||
72 | /* device queue status */ | |
73 | #define CQHCI_DQS 0x30 | |
74 | ||
75 | /* device pending tasks */ | |
76 | #define CQHCI_DPT 0x34 | |
77 | ||
78 | /* task clear */ | |
79 | #define CQHCI_TCLR 0x38 | |
80 | ||
81 | /* send status config 1 */ | |
82 | #define CQHCI_SSC1 0x40 | |
68895644 | 83 | #define CQHCI_SSC1_CBC_MASK GENMASK(19, 16) |
a4080225 VG |
84 | |
85 | /* send status config 2 */ | |
86 | #define CQHCI_SSC2 0x44 | |
87 | ||
88 | /* response for dcmd */ | |
89 | #define CQHCI_CRDCT 0x48 | |
90 | ||
91 | /* response mode error mask */ | |
92 | #define CQHCI_RMEM 0x50 | |
93 | ||
94 | /* task error info */ | |
95 | #define CQHCI_TERRI 0x54 | |
96 | ||
97 | #define CQHCI_TERRI_C_INDEX(x) ((x) & GENMASK(5, 0)) | |
98 | #define CQHCI_TERRI_C_TASK(x) (((x) & GENMASK(12, 8)) >> 8) | |
99 | #define CQHCI_TERRI_C_VALID(x) ((x) & BIT(15)) | |
100 | #define CQHCI_TERRI_D_INDEX(x) (((x) & GENMASK(21, 16)) >> 16) | |
101 | #define CQHCI_TERRI_D_TASK(x) (((x) & GENMASK(28, 24)) >> 24) | |
102 | #define CQHCI_TERRI_D_VALID(x) ((x) & BIT(31)) | |
103 | ||
104 | /* command response index */ | |
105 | #define CQHCI_CRI 0x58 | |
106 | ||
107 | /* command response argument */ | |
108 | #define CQHCI_CRA 0x5C | |
109 | ||
110 | #define CQHCI_INT_ALL 0xF | |
111 | #define CQHCI_IC_DEFAULT_ICCTH 31 | |
112 | #define CQHCI_IC_DEFAULT_ICTOVAL 1 | |
113 | ||
114 | /* attribute fields */ | |
0562315b AH |
115 | #define CQHCI_VALID(x) (((x) & 1) << 0) |
116 | #define CQHCI_END(x) (((x) & 1) << 1) | |
117 | #define CQHCI_INT(x) (((x) & 1) << 2) | |
118 | #define CQHCI_ACT(x) (((x) & 0x7) << 3) | |
a4080225 VG |
119 | |
120 | /* data command task descriptor fields */ | |
0562315b AH |
121 | #define CQHCI_FORCED_PROG(x) (((x) & 1) << 6) |
122 | #define CQHCI_CONTEXT(x) (((x) & 0xF) << 7) | |
123 | #define CQHCI_DATA_TAG(x) (((x) & 1) << 11) | |
124 | #define CQHCI_DATA_DIR(x) (((x) & 1) << 12) | |
125 | #define CQHCI_PRIORITY(x) (((x) & 1) << 13) | |
126 | #define CQHCI_QBAR(x) (((x) & 1) << 14) | |
127 | #define CQHCI_REL_WRITE(x) (((x) & 1) << 15) | |
128 | #define CQHCI_BLK_COUNT(x) (((x) & 0xFFFF) << 16) | |
129 | #define CQHCI_BLK_ADDR(x) (((x) & 0xFFFFFFFF) << 32) | |
a4080225 VG |
130 | |
131 | /* direct command task descriptor fields */ | |
0562315b AH |
132 | #define CQHCI_CMD_INDEX(x) (((x) & 0x3F) << 16) |
133 | #define CQHCI_CMD_TIMING(x) (((x) & 1) << 22) | |
134 | #define CQHCI_RESP_TYPE(x) (((x) & 0x3) << 23) | |
a4080225 VG |
135 | |
136 | /* transfer descriptor fields */ | |
0562315b AH |
137 | #define CQHCI_DAT_LENGTH(x) (((x) & 0xFFFF) << 16) |
138 | #define CQHCI_DAT_ADDR_LO(x) (((x) & 0xFFFFFFFF) << 32) | |
139 | #define CQHCI_DAT_ADDR_HI(x) (((x) & 0xFFFFFFFF) << 0) | |
a4080225 VG |
140 | |
141 | struct cqhci_host_ops; | |
142 | struct mmc_host; | |
c46d089a | 143 | struct mmc_request; |
a4080225 VG |
144 | struct cqhci_slot; |
145 | ||
146 | struct cqhci_host { | |
147 | const struct cqhci_host_ops *ops; | |
148 | void __iomem *mmio; | |
149 | struct mmc_host *mmc; | |
150 | ||
151 | spinlock_t lock; | |
152 | ||
153 | /* relative card address of device */ | |
154 | unsigned int rca; | |
155 | ||
156 | /* 64 bit DMA */ | |
157 | bool dma64; | |
158 | int num_slots; | |
159 | int qcnt; | |
160 | ||
161 | u32 dcmd_slot; | |
162 | u32 caps; | |
163 | #define CQHCI_TASK_DESC_SZ_128 0x1 | |
164 | ||
165 | u32 quirks; | |
166 | #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ 0x1 | |
167 | ||
168 | bool enabled; | |
169 | bool halted; | |
170 | bool init_done; | |
171 | bool activated; | |
172 | bool waiting_for_idle; | |
173 | bool recovery_halt; | |
174 | ||
175 | size_t desc_size; | |
176 | size_t data_size; | |
177 | ||
178 | u8 *desc_base; | |
179 | ||
180 | /* total descriptor size */ | |
181 | u8 slot_sz; | |
182 | ||
183 | /* 64/128 bit depends on CQHCI_CFG */ | |
184 | u8 task_desc_len; | |
185 | ||
186 | /* 64 bit on 32-bit arch, 128 bit on 64-bit */ | |
187 | u8 link_desc_len; | |
188 | ||
189 | u8 *trans_desc_base; | |
190 | /* same length as transfer descriptor */ | |
191 | u8 trans_desc_len; | |
192 | ||
193 | dma_addr_t desc_dma_base; | |
194 | dma_addr_t trans_desc_dma_base; | |
195 | ||
196 | struct completion halt_comp; | |
197 | wait_queue_head_t wait_queue; | |
198 | struct cqhci_slot *slot; | |
199 | }; | |
200 | ||
201 | struct cqhci_host_ops { | |
202 | void (*dumpregs)(struct mmc_host *mmc); | |
203 | void (*write_l)(struct cqhci_host *host, u32 val, int reg); | |
204 | u32 (*read_l)(struct cqhci_host *host, int reg); | |
205 | void (*enable)(struct mmc_host *mmc); | |
206 | void (*disable)(struct mmc_host *mmc, bool recovery); | |
c46d089a SK |
207 | void (*update_dcmd_desc)(struct mmc_host *mmc, struct mmc_request *mrq, |
208 | u64 *data); | |
a4080225 VG |
209 | }; |
210 | ||
211 | static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg) | |
212 | { | |
213 | if (unlikely(host->ops->write_l)) | |
214 | host->ops->write_l(host, val, reg); | |
215 | else | |
216 | writel_relaxed(val, host->mmio + reg); | |
217 | } | |
218 | ||
219 | static inline u32 cqhci_readl(struct cqhci_host *host, int reg) | |
220 | { | |
221 | if (unlikely(host->ops->read_l)) | |
222 | return host->ops->read_l(host, reg); | |
223 | else | |
224 | return readl_relaxed(host->mmio + reg); | |
225 | } | |
226 | ||
227 | struct platform_device; | |
228 | ||
229 | irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error, | |
230 | int data_error); | |
231 | int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64); | |
232 | struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev); | |
233 | int cqhci_suspend(struct mmc_host *mmc); | |
234 | int cqhci_resume(struct mmc_host *mmc); | |
235 | ||
236 | #endif |