1 /*
2 * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef _ROM_DRIVER_CHIP_SDMMC__CORE_H_
31 #define _ROM_DRIVER_CHIP_SDMMC__CORE_H_
32
33 //#include "rom_debug.h"
34 #include "rom_debug.h"
35
36 #include "card.h"
37
38 #ifdef CONFIG_USE_SDIO
39 #include "sdio.h"
40 #endif
41 #include "sdmmc.h"
42
43 #include "_sdhost.h"
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 struct mmc_data {
50 uint32_t blksz; /* data block size */
51 uint32_t blocks; /* number of blocks */
52 uint32_t flags;
53
54 #define MMC_DATA_WRITE (1 << 8)
55 #define MMC_DATA_READ (1 << 9)
56 #define MMC_DATA_STREAM (1 << 10)
57
58 uint32_t bytes_xfered;
59 uint32_t sg_len; /* size of scatter list */
60 struct scatterlist *sg; /* I/O scatter list */
61 };
62
63 struct mmc_command {
64 uint32_t opcode;
65 uint32_t arg;
66 uint32_t resp[4];
67 uint32_t flags; /* expected response type */
68 /* data transfer */
69 volatile uint32_t stop :1,
70 boot :1,
71 vol_switch :1;
72
73 #define MMC_RSP_MASK (0x1f << 0)
74 #define MMC_RSP_PRESENT (1 << 0)
75 #define MMC_RSP_136 (1 << 1) /* 136 bit response */
76 #define MMC_RSP_CRC (1 << 2) /* expect valid crc */
77 #define MMC_RSP_BUSY (1 << 3) /* card may send busy */
78 #define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
79
80 #define MMC_CMD_MASK (3 << 5) /* non-SPI command type */
81 #define MMC_CMD_AC (0 << 5) /* addressed comamnd without data transfer */
82 #define MMC_CMD_ADTC (1 << 5) /* addressed command with data transfer */
83 #define MMC_CMD_BC (2 << 5) /* broadcast command without response */
84 #define MMC_CMD_BCR (3 << 5) /* broadcast command with response */
85
86 #define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
87 #define MMC_RSP_SPI_S2 (1 << 8) /* second byte */
88 #define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */
89 #define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */
90
91 /* These are the native response types, and correspond to valid bit
92 * patterns of the above flags. One additional valid pattern
93 * is all zeros, which means we don't expect a response.
94 */
95 #define MMC_RSP_NONE (0)
96 #define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
97 #define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
98 #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
99 #define MMC_RSP_R3 (MMC_RSP_PRESENT)
100 #define MMC_RSP_R4 (MMC_RSP_PRESENT)
101 #define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
102 #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
103 #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
104
105 #define mmc_resp_type(cmd) ((cmd)->flags & MMC_RSP_MASK)
106
107 /*
108 * These are the SPI response types for MMC, SD, and SDIO cards.
109 * Commands return R1, with maybe more info. Zero is an error type;
110 * callers must always provide the appropriate MMC_RSP_SPI_Rx flags.
111 */
112 #define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
113 #define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
114 #define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
115 #define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
116 #define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
117 #define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
118 #define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
119
120 /* These are the command types. */
121 #define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
122
123 #if ((defined CONFIG_USE_SD) || (defined CONFIG_USE_MMC))
124 uint32_t retries; /* max number of retries */
125
126 /* Standard errno values are used for errors, but some have specific
127 * meaning in the MMC layer:
128 *
129 * ETIMEDOUT Card took too long to respond
130 * EILSEQ Basic format problem with the received or sent data
131 * (e.g. CRC check failed, incorrect opcode in response
132 * or bad end bit)
133 * EINVAL Request cannot be performed because of restrictions
134 * in hardware and/or the driver
135 * ENOMEDIUM Host can determine that the slot is empty and is
136 * actively failing requests
137 */
138 uint32_t erase_timeout; /* in milliseconds */
139 #endif
140
141 struct mmc_data *data; /* data segment associated with cmd */
142 };
143
144 struct mmc_request {
145 //struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */
146 struct mmc_command *cmd;
147 struct mmc_data *data;
148 //struct mmc_command *stop;
149
150 //struct completion completion;
151 //void (*done)(struct mmc_request *); /* completion function */
152 };
153
154 #define UNSTUFF_BITS(resp,start,size) \
155 ({ \
156 const int32_t __size = size; \
157 const uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1; \
158 const int32_t __off = 3 - ((start) / 32); \
159 const int32_t __shft = (start) & 31; \
160 uint32_t __res; \
161 \
162 __res = resp[__off] >> __shft; \
163 if (__size + __shft > 32) \
164 __res |= resp[__off-1] << ((32 - __shft) % 32); \
165 __res & __mask; \
166 })
167
168 #ifdef CONFIG_USE_MMC_QUIRK
169
170 #define SDIO_ANY_ID (~0)
171
172 /*
173 * The world is not perfect and supplies us with broken mmc/sdio devices.
174 * For at least some of these bugs we need a work-around.
175 */
176
177 struct mmc_fixup {
178 /* CID-specific fields. */
179 const char *name;
180
181 /* Valid revision range */
182 uint64_t rev_start, rev_end;
183
184 int32_t manfid;
185 int16_t oemid;
186
187 /* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */
188 uint16_t cis_vendor, cis_device;
189
190 void (*vendor_fixup)(struct mmc_card *card, int32_t data);
191 int32_t data;
192 };
193
194 #define CID_MANFID_ANY (-1u)
195 #define CID_OEMID_ANY ((unsigned short) -1)
196 #define CID_NAME_ANY (NULL)
197
198 #define END_FIXUP { 0 }
199
200 #define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \
201 _cis_vendor, _cis_device, \
202 _fixup, _data) \
203 { \
204 .name = (_name), \
205 .manfid = (_manfid), \
206 .oemid = (_oemid), \
207 .rev_start = (_rev_start), \
208 .rev_end = (_rev_end), \
209 .cis_vendor = (_cis_vendor), \
210 .cis_device = (_cis_device), \
211 .vendor_fixup = (_fixup), \
212 .data = (_data), \
213 }
214
215 #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \
216 _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \
217 CID_OEMID_ANY, 0, -1ull, \
218 _vendor, _device, \
219 _fixup, _data) \
220
221 #define cid_rev(hwrev, fwrev, year, month) \
222 (((uint64_t) hwrev) << 40 | \
223 ((uint64_t) fwrev) << 32 | \
224 ((uint64_t) year) << 16 | \
225 ((uint64_t) month))
226
227 #define cid_rev_card(card) \
228 cid_rev(card->cid.hwrev, \
229 card->cid.fwrev, \
230 card->cid.year, \
231 card->cid.month)
232
233 /*
234 * This hook just adds a quirk for all sdio devices
235 */
add_quirk_for_sdio_devices(struct mmc_card * card,int32_t data)236 static void add_quirk_for_sdio_devices(struct mmc_card *card, int32_t data)
237 {
238 if (mmc_card_sdio(card))
239 card->quirks |= data;
240 }
241
add_quirk(struct mmc_card * card,int32_t data)242 static inline void add_quirk(struct mmc_card *card, int32_t data)
243 {
244 card->quirks |= data;
245 }
246
remove_quirk(struct mmc_card * card,int32_t data)247 static inline void remove_quirk(struct mmc_card *card, int32_t data)
248 {
249 card->quirks &= ~data;
250 }
251
252 /*
253 * Quirk add/remove for MMC products.
254 */
255
add_quirk_mmc(struct mmc_card * card,int data)256 static inline void add_quirk_mmc(struct mmc_card *card, int data)
257 {
258 if (mmc_card_mmc(card))
259 card->quirks |= data;
260 }
261
remove_quirk_mmc(struct mmc_card * card,int data)262 static inline void remove_quirk_mmc(struct mmc_card *card,
263 int data)
264 {
265 if (mmc_card_mmc(card))
266 card->quirks &= ~data;
267 }
268
269 /*
270 * Quirk add/remove for SD products.
271 */
272
add_quirk_sd(struct mmc_card * card,int data)273 static inline void add_quirk_sd(struct mmc_card *card, int data)
274 {
275 if (mmc_card_sd(card))
276 card->quirks |= data;
277 }
278
remove_quirk_sd(struct mmc_card * card,int data)279 static inline void remove_quirk_sd(struct mmc_card *card,
280 int data)
281 {
282 if (mmc_card_sd(card))
283 card->quirks &= ~data;
284 }
285
mmc_card_lenient_fn0(const struct mmc_card * c)286 static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
287 {
288 return c->quirks & MMC_QUIRK_LENIENT_FN0;
289 }
290
mmc_blksz_for_byte_mode(const struct mmc_card * c)291 static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
292 {
293 return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
294 }
295
296 /*
297 static inline int mmc_card_disable_cd(const struct mmc_card *c)
298 {
299 return c->quirks & MMC_QUIRK_DISABLE_CD;
300 }
301 */
302
mmc_card_nonstd_func_interface(const struct mmc_card * c)303 static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c)
304 {
305 return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF;
306 }
307
mmc_card_broken_byte_mode_512(const struct mmc_card * c)308 static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c)
309 {
310 return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512;
311 }
312
mmc_card_long_read_time(const struct mmc_card * c)313 static inline int mmc_card_long_read_time(const struct mmc_card *c)
314 {
315 return c->quirks & MMC_QUIRK_LONG_READ_TIME;
316 }
317
318 #endif
319
320 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
321 void mmc_detach_bus(struct mmc_host *host);
322
323 extern int32_t mmc_align_data_size(struct mmc_card *card, uint32_t sz);
324 extern int32_t mmc_send_status(struct mmc_card *card, uint32_t *status);
325 extern int32_t mmc_sd_switch(struct mmc_card *card, uint8_t mode, uint8_t group,
326 uint16_t value, uint8_t *resp);
327 extern void mmc_enumerate_card_info(struct mmc_card *card);
328 extern int32_t mmc_switch_to_high_speed(struct mmc_card *card);
329 extern int32_t __sdmmc_block_rw(struct mmc_card *card, uint32_t blk_num, uint32_t blk_cnt,
330 uint32_t sg_len, struct scatterlist *sg, int write);
331 extern int32_t mmc_sd_switch_hs(struct mmc_card *card);
332 extern int32_t mmc_app_set_bus_width(struct mmc_card *card, uint32_t width);
333 extern int32_t mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd);
334 extern int32_t mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq);
335 //#ifndef __CONFIG_ROM
336 extern int32_t mmc_attach_sd(struct mmc_card *card, struct mmc_host *host);
337 extern void mmc_deattach_sd(struct mmc_card *card, struct mmc_host *host);
338 //#endif
339 extern int32_t mmc_select_card(struct mmc_card *card, uint32_t select);
340 extern int32_t mmc_all_send_cid(struct mmc_host *host, uint32_t *cid);
341 extern int32_t mmc_send_relative_addr(struct mmc_host *host, uint32_t *rca);
342 extern void mmc_add_card(struct mmc_card *card);
343 #ifdef CONFIG_USE_MMC_QUIRK
344 extern void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table);
345 #endif
346
mmc_card_disable_cd(const struct mmc_card * c)347 static inline int mmc_card_disable_cd(const struct mmc_card *c)
348 {
349 #ifdef CONFIG_USE_MMC_QUIRK
350 return c->quirks & MMC_QUIRK_DISABLE_CD;
351 #else
352 return 0;
353 #endif
354 }
355
356 /**
357 * @brief Exclusively claim a host.
358 * @note Claim a host for a set of operations.
359 * @param host:
360 * @host->mmc host to claim.
361 * @retval None.
362 */
mmc_claim_host(struct mmc_host * host)363 static inline void mmc_claim_host(struct mmc_host *host)
364 {
365 HAL_SDC_Claim_Host(host);
366 }
367
368 /**
369 * @brief Release a host.
370 * @note Release a MMC host, allowing others to claim the host for their operations.
371 * @param host:
372 * @host->mmc host to release.
373 * @retval None.
374 */
mmc_release_host(struct mmc_host * host)375 static inline void mmc_release_host(struct mmc_host *host)
376 {
377 HAL_SDC_Release_Host(host);
378 }
379
380 #ifdef __cplusplus
381 }
382 #endif
383
384 #endif /* _ROM_DRIVER_CHIP_SDMMC__CORE_H_ */
385