1 | /* $NetBSD: sdmmcvar.h,v 1.21 2015/11/29 23:38:47 jmcneill Exp $ */ |
2 | /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> |
6 | * |
7 | * Permission to use, copy, modify, and distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above |
9 | * copyright notice and this permission notice appear in all copies. |
10 | * |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | */ |
19 | |
20 | #ifndef _SDMMCVAR_H_ |
21 | #define _SDMMCVAR_H_ |
22 | |
23 | #ifdef _KERNEL_OPT |
24 | #include "opt_sdmmc.h" |
25 | #endif |
26 | |
27 | #include <sys/queue.h> |
28 | #include <sys/mutex.h> |
29 | #include <sys/callout.h> |
30 | #include <sys/evcnt.h> |
31 | |
32 | #include <sys/bus.h> |
33 | |
34 | #include <dev/sdmmc/sdmmcchip.h> |
35 | #include <dev/sdmmc/sdmmcreg.h> |
36 | |
37 | #define SDMMC_SECTOR_SIZE_SB 9 |
38 | #define SDMMC_SECTOR_SIZE (1 << SDMMC_SECTOR_SIZE_SB) /* =512 */ |
39 | |
40 | struct sdmmc_csd { |
41 | int csdver; /* CSD structure format */ |
42 | u_int mmcver; /* MMC version (for CID format) */ |
43 | int capacity; /* total number of sectors */ |
44 | int read_bl_len; /* block length for reads */ |
45 | int write_bl_len; /* block length for writes */ |
46 | int r2w_factor; |
47 | int tran_speed; /* transfer speed (kbit/s) */ |
48 | int ccc; /* Card Command Class for SD */ |
49 | /* ... */ |
50 | }; |
51 | |
52 | struct sdmmc_cid { |
53 | int mid; /* manufacturer identification number */ |
54 | int oid; /* OEM/product identification number */ |
55 | char pnm[8]; /* product name (MMC v1 has the longest) */ |
56 | int rev; /* product revision */ |
57 | int psn; /* product serial number */ |
58 | int mdt; /* manufacturing date */ |
59 | }; |
60 | |
61 | struct sdmmc_scr { |
62 | int sd_spec; |
63 | int bus_width; |
64 | }; |
65 | |
66 | typedef uint32_t sdmmc_response[4]; |
67 | |
68 | struct sdmmc_softc; |
69 | |
70 | struct sdmmc_task { |
71 | void (*func)(void *arg); |
72 | void *arg; |
73 | int onqueue; |
74 | struct sdmmc_softc *sc; |
75 | TAILQ_ENTRY(sdmmc_task) next; |
76 | }; |
77 | |
78 | #define sdmmc_init_task(xtask, xfunc, xarg) \ |
79 | do { \ |
80 | (xtask)->func = (xfunc); \ |
81 | (xtask)->arg = (xarg); \ |
82 | (xtask)->onqueue = 0; \ |
83 | (xtask)->sc = NULL; \ |
84 | } while (/*CONSTCOND*/0) |
85 | |
86 | #define sdmmc_task_pending(xtask) ((xtask)->onqueue) |
87 | |
88 | struct sdmmc_command { |
89 | struct sdmmc_task c_task; /* task queue entry */ |
90 | uint16_t c_opcode; /* SD or MMC command index */ |
91 | uint32_t c_arg; /* SD/MMC command argument */ |
92 | sdmmc_response c_resp; /* response buffer */ |
93 | bus_dmamap_t c_dmamap; |
94 | int c_dmaseg; /* DMA segment number */ |
95 | int c_dmaoff; /* offset in DMA segment */ |
96 | void *c_data; /* buffer to send or read into */ |
97 | int c_datalen; /* length of data buffer */ |
98 | int c_blklen; /* block length */ |
99 | int c_flags; /* see below */ |
100 | #define SCF_ITSDONE (1U << 0) /* command is complete */ |
101 | #define SCF_RSP_PRESENT (1U << 1) |
102 | #define SCF_RSP_BSY (1U << 2) |
103 | #define SCF_RSP_136 (1U << 3) |
104 | #define SCF_RSP_CRC (1U << 4) |
105 | #define SCF_RSP_IDX (1U << 5) |
106 | #define SCF_CMD_READ (1U << 6) /* read command (data expected) */ |
107 | /* non SPI */ |
108 | #define SCF_CMD_AC (0U << 8) |
109 | #define SCF_CMD_ADTC (1U << 8) |
110 | #define SCF_CMD_BC (2U << 8) |
111 | #define SCF_CMD_BCR (3U << 8) |
112 | #define SCF_CMD_MASK (3U << 8) |
113 | /* SPI */ |
114 | #define SCF_RSP_SPI_S1 (1U << 10) |
115 | #define SCF_RSP_SPI_S2 (1U << 11) |
116 | #define SCF_RSP_SPI_B4 (1U << 12) |
117 | #define SCF_RSP_SPI_BSY (1U << 13) |
118 | /* Probing */ |
119 | #define SCF_TOUT_OK (1U << 14) /* command timeout expected */ |
120 | /* response types */ |
121 | #define SCF_RSP_R0 0 /* none */ |
122 | #define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) |
123 | #define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY) |
124 | #define SCF_RSP_R2 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_136) |
125 | #define SCF_RSP_R3 (SCF_RSP_PRESENT) |
126 | #define SCF_RSP_R4 (SCF_RSP_PRESENT) |
127 | #define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) |
128 | #define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY) |
129 | #define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) |
130 | #define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) |
131 | #define SCF_RSP_MASK (0x1f << 1) |
132 | /* SPI */ |
133 | #define SCF_RSP_SPI_R1 (SCF_RSP_SPI_S1) |
134 | #define SCF_RSP_SPI_R1B (SCF_RSP_SPI_S1|SCF_RSP_SPI_BSY) |
135 | #define SCF_RSP_SPI_R2 (SCF_RSP_SPI_S1|SCF_RSP_SPI_S2) |
136 | #define SCF_RSP_SPI_R3 (SCF_RSP_SPI_S1|SCF_RSP_SPI_B4) |
137 | #define SCF_RSP_SPI_R4 (SCF_RSP_SPI_S1|SCF_RSP_SPI_B4) |
138 | #define SCF_RSP_SPI_R5 (SCF_RSP_SPI_S1|SCF_RSP_SPI_S2) |
139 | #define SCF_RSP_SPI_R7 (SCF_RSP_SPI_S1|SCF_RSP_SPI_B4) |
140 | #define SCF_RSP_SPI_MASK (0xf << 10) |
141 | int c_error; /* errno value on completion */ |
142 | |
143 | /* Host controller owned fields for data xfer in progress */ |
144 | int c_resid; /* remaining I/O */ |
145 | u_char *c_buf; /* remaining data */ |
146 | }; |
147 | |
148 | /* |
149 | * Decoded PC Card 16 based Card Information Structure (CIS), |
150 | * per card (function 0) and per function (1 and greater). |
151 | */ |
152 | struct sdmmc_cis { |
153 | uint16_t manufacturer; |
154 | #define SDMMC_VENDOR_INVALID 0xffff |
155 | uint16_t product; |
156 | #define SDMMC_PRODUCT_INVALID 0xffff |
157 | uint8_t function; |
158 | #define SDMMC_FUNCTION_INVALID 0xff |
159 | u_char cis1_major; |
160 | u_char cis1_minor; |
161 | char cis1_info_buf[256]; |
162 | char *cis1_info[4]; |
163 | }; |
164 | |
165 | /* |
166 | * Structure describing either an SD card I/O function or a SD/MMC |
167 | * memory card from a "stack of cards" that responded to CMD2. For a |
168 | * combo card with one I/O function and one memory card, there will be |
169 | * two of these structures allocated. Each card slot has such a list |
170 | * of sdmmc_function structures. |
171 | */ |
172 | struct sdmmc_function { |
173 | /* common members */ |
174 | struct sdmmc_softc *sc; /* card slot softc */ |
175 | uint16_t rca; /* relative card address */ |
176 | int interface; /* SD/MMC:0, SDIO:standard interface */ |
177 | int width; /* bus width */ |
178 | int flags; |
179 | #define SFF_ERROR 0x0001 /* function is poo; ignore it */ |
180 | #define SFF_SDHC 0x0002 /* SD High Capacity card */ |
181 | SIMPLEQ_ENTRY(sdmmc_function) sf_list; |
182 | /* SD card I/O function members */ |
183 | int number; /* I/O function number or -1 */ |
184 | device_t child; /* function driver */ |
185 | struct sdmmc_cis cis; /* decoded CIS */ |
186 | /* SD/MMC memory card members */ |
187 | struct sdmmc_csd csd; /* decoded CSD value */ |
188 | struct sdmmc_cid cid; /* decoded CID value */ |
189 | sdmmc_response raw_cid; /* temp. storage for decoding */ |
190 | uint32_t raw_scr[2]; |
191 | struct sdmmc_scr scr; /* decoded SCR value */ |
192 | |
193 | void *bbuf; /* bounce buffer */ |
194 | bus_dmamap_t bbuf_dmap; /* DMA map for bounce buffer */ |
195 | bus_dmamap_t sseg_dmap; /* DMA map for single segment */ |
196 | }; |
197 | |
198 | /* |
199 | * Structure describing a single SD/MMC/SDIO card slot. |
200 | */ |
201 | struct sdmmc_softc { |
202 | device_t sc_dev; /* base device */ |
203 | #define SDMMCDEVNAME(sc) (device_xname(sc->sc_dev)) |
204 | |
205 | sdmmc_chipset_tag_t sc_sct; /* host controller chipset tag */ |
206 | sdmmc_spi_chipset_tag_t sc_spi_sct; |
207 | sdmmc_chipset_handle_t sc_sch; /* host controller chipset handle */ |
208 | bus_dma_tag_t sc_dmat; |
209 | bus_dmamap_t sc_dmap; |
210 | #define SDMMC_MAXNSEGS ((MAXPHYS / PAGE_SIZE) + 1) |
211 | |
212 | struct kmutex sc_mtx; /* lock around host controller */ |
213 | int sc_dying; /* bus driver is shutting down */ |
214 | |
215 | uint32_t sc_flags; |
216 | #define SMF_INITED 0x0001 |
217 | #define SMF_SD_MODE 0x0002 /* host in SD mode (MMC otherwise) */ |
218 | #define SMF_IO_MODE 0x0004 /* host in I/O mode (SD mode only) */ |
219 | #define SMF_MEM_MODE 0x0008 /* host in memory mode (SD or MMC) */ |
220 | #define SMF_CARD_PRESENT 0x4000 /* card presence noticed */ |
221 | #define SMF_CARD_ATTACHED 0x8000 /* card driver(s) attached */ |
222 | #define SMF_UHS_MODE 0x10000 /* host in UHS mode */ |
223 | |
224 | uint32_t sc_caps; /* host capability */ |
225 | #define SMC_CAPS_AUTO_STOP 0x0001 /* send CMD12 automagically by host */ |
226 | #define SMC_CAPS_4BIT_MODE 0x0002 /* 4-bits data bus width */ |
227 | #define SMC_CAPS_DMA 0x0004 /* DMA transfer */ |
228 | #define SMC_CAPS_SPI_MODE 0x0008 /* SPI mode */ |
229 | #define SMC_CAPS_POLL_CARD_DET 0x0010 /* Polling card detect */ |
230 | #define SMC_CAPS_SINGLE_ONLY 0x0020 /* only single read/write */ |
231 | #define SMC_CAPS_8BIT_MODE 0x0040 /* 8-bits data bus width */ |
232 | #define SMC_CAPS_MULTI_SEG_DMA 0x0080 /* multiple segment DMA transfer */ |
233 | #define SMC_CAPS_SD_HIGHSPEED 0x0100 /* SD high-speed timing */ |
234 | #define SMC_CAPS_MMC_HIGHSPEED 0x0200 /* MMC high-speed timing */ |
235 | #define SMC_CAPS_UHS_SDR50 0x1000 /* UHS SDR50 timing */ |
236 | #define SMC_CAPS_UHS_SDR104 0x2000 /* UHS SDR104 timing */ |
237 | #define SMC_CAPS_UHS_DDR50 0x4000 /* UHS DDR50 timing */ |
238 | #define SMC_CAPS_UHS_MASK 0x7000 |
239 | #define SMC_CAPS_MMC_HS200 0x8000 /* eMMC HS200 timing */ |
240 | |
241 | /* function */ |
242 | int sc_function_count; /* number of I/O functions (SDIO) */ |
243 | struct sdmmc_function *sc_card; /* selected card */ |
244 | struct sdmmc_function *sc_fn0; /* function 0, the card itself */ |
245 | SIMPLEQ_HEAD(, sdmmc_function) sf_head; /* list of card functions */ |
246 | |
247 | /* task queue */ |
248 | struct lwp *sc_tskq_lwp; /* asynchronous tasks */ |
249 | TAILQ_HEAD(, sdmmc_task) sc_tskq; /* task thread work queue */ |
250 | struct kmutex sc_tskq_mtx; |
251 | struct kcondvar sc_tskq_cv; |
252 | |
253 | /* discover task */ |
254 | struct sdmmc_task sc_discover_task; /* card attach/detach task */ |
255 | struct kmutex sc_discover_task_mtx; |
256 | |
257 | /* interrupt task */ |
258 | struct sdmmc_task sc_intr_task; /* card interrupt task */ |
259 | struct kmutex sc_intr_task_mtx; |
260 | TAILQ_HEAD(, sdmmc_intr_handler) sc_intrq; /* interrupt handlers */ |
261 | |
262 | u_int sc_clkmin; /* host min bus clock */ |
263 | u_int sc_clkmax; /* host max bus clock */ |
264 | u_int sc_busclk; /* host bus clock */ |
265 | bool sc_busddr; /* host bus clock is in DDR mode */ |
266 | int sc_buswidth; /* host bus width */ |
267 | const char *sc_transfer_mode; /* current transfer mode */ |
268 | |
269 | callout_t sc_card_detect_ch; /* polling card insert/remove */ |
270 | |
271 | /* event counters */ |
272 | struct evcnt sc_ev_xfer; /* xfer count */ |
273 | struct evcnt sc_ev_xfer_aligned[8]; /* aligned xfer counts */ |
274 | struct evcnt sc_ev_xfer_unaligned; /* unaligned xfer count */ |
275 | struct evcnt sc_ev_xfer_error; /* error xfer count */ |
276 | }; |
277 | |
278 | /* |
279 | * Attach devices at the sdmmc bus. |
280 | */ |
281 | struct sdmmc_attach_args { |
282 | uint16_t manufacturer; |
283 | uint16_t product; |
284 | int interface; |
285 | struct sdmmc_function *sf; |
286 | }; |
287 | |
288 | struct sdmmc_product { |
289 | uint16_t pp_vendor; |
290 | uint16_t pp_product; |
291 | const char *pp_cisinfo[4]; |
292 | }; |
293 | |
294 | #ifndef IPL_SDMMC |
295 | #define IPL_SDMMC IPL_BIO |
296 | #endif |
297 | |
298 | #ifndef splsdmmc |
299 | #define splsdmmc() splbio() |
300 | #endif |
301 | |
302 | #define SDMMC_LOCK(sc) |
303 | #define SDMMC_UNLOCK(sc) |
304 | |
305 | #ifdef SDMMC_DEBUG |
306 | extern int sdmmcdebug; |
307 | #endif |
308 | |
309 | void sdmmc_add_task(struct sdmmc_softc *, struct sdmmc_task *); |
310 | void sdmmc_del_task(struct sdmmc_task *); |
311 | |
312 | struct sdmmc_function *sdmmc_function_alloc(struct sdmmc_softc *); |
313 | void sdmmc_function_free(struct sdmmc_function *); |
314 | int sdmmc_set_bus_power(struct sdmmc_softc *, uint32_t, uint32_t); |
315 | int sdmmc_mmc_command(struct sdmmc_softc *, struct sdmmc_command *); |
316 | int sdmmc_app_command(struct sdmmc_softc *, struct sdmmc_function *, |
317 | struct sdmmc_command *); |
318 | void sdmmc_stop_transmission(struct sdmmc_softc *); |
319 | void sdmmc_go_idle_state(struct sdmmc_softc *); |
320 | int sdmmc_select_card(struct sdmmc_softc *, struct sdmmc_function *); |
321 | int sdmmc_set_relative_addr(struct sdmmc_softc *, struct sdmmc_function *); |
322 | |
323 | void sdmmc_intr_enable(struct sdmmc_function *); |
324 | void sdmmc_intr_disable(struct sdmmc_function *); |
325 | void *sdmmc_intr_establish(device_t, int (*)(void *), void *, const char *); |
326 | void sdmmc_intr_disestablish(void *); |
327 | void sdmmc_intr_task(void *); |
328 | |
329 | int sdmmc_decode_csd(struct sdmmc_softc *, sdmmc_response, |
330 | struct sdmmc_function *); |
331 | int sdmmc_decode_cid(struct sdmmc_softc *, sdmmc_response, |
332 | struct sdmmc_function *); |
333 | void sdmmc_print_cid(struct sdmmc_cid *); |
334 | #ifdef SDMMC_DUMP_CSD |
335 | void sdmmc_print_csd(sdmmc_response, struct sdmmc_csd *); |
336 | #endif |
337 | void sdmmc_dump_data(const char *, void *, size_t); |
338 | |
339 | int sdmmc_io_enable(struct sdmmc_softc *); |
340 | void sdmmc_io_scan(struct sdmmc_softc *); |
341 | int sdmmc_io_init(struct sdmmc_softc *, struct sdmmc_function *); |
342 | uint8_t sdmmc_io_read_1(struct sdmmc_function *, int); |
343 | uint16_t sdmmc_io_read_2(struct sdmmc_function *, int); |
344 | uint32_t sdmmc_io_read_4(struct sdmmc_function *, int); |
345 | int sdmmc_io_read_multi_1(struct sdmmc_function *, int, u_char *, int); |
346 | void sdmmc_io_write_1(struct sdmmc_function *, int, uint8_t); |
347 | void sdmmc_io_write_2(struct sdmmc_function *, int, uint16_t); |
348 | void sdmmc_io_write_4(struct sdmmc_function *, int, uint32_t); |
349 | int sdmmc_io_write_multi_1(struct sdmmc_function *, int, u_char *, int); |
350 | int sdmmc_io_function_enable(struct sdmmc_function *); |
351 | void sdmmc_io_function_disable(struct sdmmc_function *); |
352 | |
353 | int sdmmc_read_cis(struct sdmmc_function *, struct sdmmc_cis *); |
354 | void sdmmc_print_cis(struct sdmmc_function *); |
355 | void sdmmc_check_cis_quirks(struct sdmmc_function *); |
356 | |
357 | int sdmmc_mem_enable(struct sdmmc_softc *); |
358 | void sdmmc_mem_scan(struct sdmmc_softc *); |
359 | int sdmmc_mem_init(struct sdmmc_softc *, struct sdmmc_function *); |
360 | int sdmmc_mem_send_op_cond(struct sdmmc_softc *, uint32_t, uint32_t *); |
361 | int sdmmc_mem_send_if_cond(struct sdmmc_softc *, uint32_t, uint32_t *); |
362 | int sdmmc_mem_set_blocklen(struct sdmmc_softc *, struct sdmmc_function *, |
363 | int); |
364 | int sdmmc_mem_read_block(struct sdmmc_function *, uint32_t, u_char *, |
365 | size_t); |
366 | int sdmmc_mem_write_block(struct sdmmc_function *, uint32_t, u_char *, |
367 | size_t); |
368 | |
369 | #endif /* _SDMMCVAR_H_ */ |
370 | |