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