source: umon/ports/beagleboneblack/am335x_mmc.c @ 426fc71

Last change on this file since 426fc71 was 426fc71, checked in by Jarielle Catbagan <jcatbagan93@…>, on 08/04/15 at 18:03:28

BBB: Migrate MMC1 clock enable from am335x_mmc.c:mmcInit() to cpuio.c:initCPUio()

  • Property mode set to 100644
File size: 15.6 KB
Line 
1/*
2 * Copyright (c) 2015 Jarielle Catbagan <jcatbagan93@gmail.com>
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 */
8
9#include "genlib.h"
10#include "cli.h"
11#include "stddefs.h"
12#include "am335x.h"
13#include "am335x_mmc.h"
14
15uint16_t mmcrca;
16int mmcInum;
17
18char *mmcHelp[] = {
19        "MultiMediaCard Interface",
20        "[options] {operation} [args]...",
21#if INCLUDE_VERBOSEHELP
22        "",
23        "Options:",
24        " -i ## interface # (default is 0)",
25        " -v    additive verbosity",
26        "",
27        "Operations:",
28        " init",
29        " read {dest} {blk} {blktot}",
30        " write {source} {blk} {blktot}",
31#endif /* INCLUDE_VERBOSEHELP */
32        0
33};
34
35int
36mmccmd(uint32_t cmd, uint32_t arg, uint32_t resp[4])
37{
38        /* Clear the SD_STAT register for proper update of status bits after CMD invocation */
39        MMC1_REG(SD_STAT) = 0xFFFFFFFF;
40
41        MMC1_REG(SD_ARG) = arg;
42        MMC1_REG(SD_CMD) = cmd;
43
44        /* CMDx complete? */
45        while (!(MMC1_REG(SD_STAT) & (SD_STAT_CC | SD_STAT_ERRI)));
46
47        resp[0] = MMC1_REG(SD_RSP10);
48        resp[1] = MMC1_REG(SD_RSP32);
49        resp[2] = MMC1_REG(SD_RSP54);
50        resp[3] = MMC1_REG(SD_RSP76);
51
52        /* CMDx error? */
53        if (MMC1_REG(SD_STAT) & SD_STAT_ERRI)
54                return(-1);
55        else
56                return(0);
57}
58
59int
60mmc(int argc, char *argv[])
61{
62        char *cmd, *buf;
63        int opt, verbose, mmcret, blknum, blkcnt;
64
65        verbose = 0;
66
67        while ((opt = getopt(argc, argv, "i:v")) != -1) {
68                switch (opt) {
69                        case 'i':
70                                mmcInum = atoi(optarg);
71                                break;
72                        case 'v':
73                                verbose++;
74                                break;
75                        default:
76                                return(CMD_PARAM_ERROR);
77                }
78        }
79
80        if (argc < optind + 1)
81                return(CMD_PARAM_ERROR);
82
83        cmd = argv[optind];
84
85        if (mmcInstalled(mmcInum) == 0) {
86                printf("MMC not installed\n");
87                return(CMD_FAILURE);
88        }
89
90        if (strcmp(cmd, "init") == 0) {
91                mmcret = mmcInit(mmcInum, verbose);
92                if(mmcret < 0) {
93                        printf("mmcInit returned %d\n", mmcret);
94                        return(CMD_FAILURE);
95                }
96        }
97        else if (strcmp(cmd, "read") == 0) {
98                if (argc != (optind + 4))
99                        return(CMD_PARAM_ERROR);
100
101                buf = (char *)strtoul(argv[optind + 1], 0, 0);
102                blknum = strtoul(argv[optind + 2], 0, 0);
103                blkcnt = strtoul(argv[optind + 3], 0, 0);
104
105                mmcret = mmcRead(mmcInum, buf, blknum, blkcnt);
106                if (mmcret < 0) {
107                        printf("mmcRead returned %d\n", mmcret);
108                        return(CMD_FAILURE);
109                }
110        }
111        else if (strcmp(cmd, "write") == 0) {
112                if (argc != (optind + 4))
113                        return(CMD_PARAM_ERROR);
114
115                buf = (char *)strtoul(argv[optind + 1], 0, 0);
116                blknum = strtoul(argv[optind + 2], 0, 0);
117                blkcnt = strtoul(argv[optind + 3], 0, 0);
118
119                mmcret = mmcWrite(mmcInum, buf, blknum, blkcnt);
120                if (mmcret < 0) {
121                        printf("mmcWrite returned %d\n", mmcret);
122                        return(CMD_FAILURE);
123                }
124        }
125        else {
126                printf("mmc op <%s> not found\n", cmd);
127                return(CMD_FAILURE);
128        }
129
130        return(CMD_SUCCESS);
131}
132
133int
134mmcInit(int interface, int verbose)
135{
136        uint32_t cmd, arg, resp[4];
137
138        /* Reset the MMC1 Controller */
139        MMC1_REG(SD_SYSCONFIG) = SD_SYSCONFIG_SOFTRESET;
140        while (!(MMC1_REG(SD_SYSSTATUS) & SD_SYSSTATUS_RESETDONE));
141
142        /* Reset the command and data lines */
143        MMC1_REG(SD_SYSCTL) |= SD_SYSCTL_SRA;
144        while (MMC1_REG(SD_SYSCTL) & SD_SYSCTL_SRA);
145
146        /* Configure the MMC1 controller capabilities to enable 3.0 V operating voltage */
147        MMC1_REG(SD_CAPA) |= SD_CAPA_VS30;
148
149        /* Configure SD_IE register to update certain status bits in SD_STAT */
150        MMC1_REG(SD_IE) = SD_IE_BADA_ENABLE | SD_IE_CERR_ENABLE | SD_IE_ACE_ENABLE |
151                SD_IE_DEB_ENABLE | SD_IE_DCRC_ENABLE | SD_IE_DTO_ENABLE | SD_IE_CIE_ENABLE |
152                SD_IE_CEB_ENABLE | SD_IE_CCRC_ENABLE | SD_IE_CIRQ_ENABLE | SD_IE_CREM_ENABLE |
153                SD_IE_CINS_ENABLE | SD_IE_BRR_ENABLE | SD_IE_BWR_ENABLE |
154                SD_IE_TC_ENABLE | SD_IE_CC_ENABLE;
155
156        /* Configure the operating voltage to 3.0 V */
157        MMC1_REG(SD_HCTL) &= ~(SD_HCTL_SDVS);
158        MMC1_REG(SD_HCTL) |= SD_HCTL_SDVS_VS30;
159
160        /* Turn on the bus */
161        MMC1_REG(SD_HCTL) |= SD_HCTL_SDBP;
162        while (!(MMC1_REG(SD_HCTL) & SD_HCTL_SDBP));
163
164        /* Enable the internal clock */
165        MMC1_REG(SD_SYSCTL) |= SD_SYSCTL_ICE;
166
167        /* Configure Clock Frequency Select to 100 KHz */
168        MMC1_REG(SD_SYSCTL) = (MMC1_REG(SD_SYSCTL) & ~SD_SYSCTL_CLKD) | (960 << 6);
169
170        /* Wait for clock to stabilize */
171        while (!(MMC1_REG(SD_SYSCTL) & SD_SYSCTL_ICS));
172
173        /* Configure SD_SYSCONFIG */
174        MMC1_REG(SD_SYSCONFIG) &= ~(SD_SYSCONFIG_CLOCKACTIVITY | SD_SYSCONFIG_SIDLEMODE);
175        MMC1_REG(SD_SYSCONFIG) |= SD_SYSCONFIG_SIDLEMODE_WKUP | SD_SYSCONFIG_ENAWAKEUP_ENABLE |
176                SD_SYSCONFIG_AUTOIDLE_AUTOGATE;
177
178        /* Enable the clock to the eMMC */
179        MMC1_REG(SD_SYSCTL) |= SD_SYSCTL_CEN;
180
181        /* Perform the Initialization Stream as specified in the AM335x TRM, Section 18.3.3.2
182           "Card Detection, Identification, and Selection" */
183        MMC1_REG(SD_CON) |= SD_CON_INIT;
184        /* Clear the SD_STAT register */
185        MMC1_REG(SD_STAT) = 0xFFFFFFFF;
186        MMC1_REG(SD_ARG) = 0x00000000;
187        MMC1_REG(SD_CMD) = 0x00000000;
188        while (!(MMC1_REG(SD_STAT) & SD_STAT_CC));
189        /* Clear CC flag in SD_STAT */
190        MMC1_REG(SD_STAT) |= SD_STAT_CC;
191        MMC1_REG(SD_CON) &= ~SD_CON_INIT;
192
193        /* Clear the SD_STAT register */
194        MMC1_REG(SD_STAT) = 0xFFFFFFFF;
195
196        /* Enable open-drain mode until we enter Stand-by State as illustrated in the
197           JEDEC JESD84-A43 Embedded MultiMediaCard Product Standard specification, Table 5 */
198        MMC1_REG(SD_CON) |= SD_CON_OD;
199
200        /* Send CMD0/GO_IDLE_STATE to reset the eMMC on MMC1 interface */
201        arg = 0x00000000;
202        cmd = SD_CMD_CMD0_GO_IDLE_STATE | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
203                SD_CMD_CICE_DISABLE | SD_CMD_CCCE_DISABLE | SD_CMD_RSP_TYPE_NO_RESPONSE;
204        if (mmccmd(cmd, arg, resp) == -1)
205                return(-1);
206
207        /* Send CMD1 and poll busy bit in response */
208        do {
209                arg = 0x40FF8000;
210                cmd = SD_CMD_CMD1_SEND_OP_COND | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
211                        SD_CMD_CICE_DISABLE | SD_CMD_CCCE_DISABLE | SD_CMD_RSP_TYPE_R3;
212                if (mmccmd(cmd, arg, resp) == -1)
213                        return(-1);
214        } while (!(MMC1_REG(SD_RSP10) & 0x80000000));
215
216        /* Send CMD2, i.e. ALL_SEND_CID */
217        arg = 0x00000000;
218        cmd = SD_CMD_CMD2_ALL_SEND_CID | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
219                SD_CMD_CICE_DISABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R2;
220        if (mmccmd(cmd, arg, resp) == -1)
221                return(-1);
222
223        /* Set RCA of eMMC */
224        mmcrca = 0x3A3A;
225
226        /* Send CMD3 to set the relative card address (RCA) of the eMMC */
227        arg = (mmcrca << 16) & 0xFFFF0000;
228        cmd = SD_CMD_CMD3_SET_RELATIVE_ADDR | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
229                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
230        if (mmccmd(cmd, arg, resp) == -1)
231                return(-1);
232
233        /* Wait for the eMMC to enter Stand-by State */
234        do {
235                /* Send CMD13 to get the status of the MMC */
236                arg = (mmcrca << 16) & 0xFFFF0000;
237                cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
238                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
239                if (mmccmd(cmd, arg, resp) == -1)
240                        return(-1);
241        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_STANDBY);
242
243        /* Disable open-drain mode */
244        MMC1_REG(SD_CON) &= ~SD_CON_OD;
245
246        /* Send CMD7 to put the eMMC into Transfer State */
247        arg = (mmcrca << 16) & 0xFFFF0000;
248        cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
249                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
250        if (mmccmd(cmd, arg, resp) == -1)
251                return(-1);
252
253        /* Wait for eMMC to enter Transfer State */
254        do {
255                /* Send CMD13 to get the status of the eMMC */
256                arg = (mmcrca << 16) & 0xFFFF0000;
257                cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
258                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
259                if (mmccmd(cmd, arg, resp) == -1)
260                        return(-1);
261        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER);
262
263        /* Send CMD6 to change bus-width to 8-bits */
264        arg = (3 << 24) | (183 << 16) | (2 << 8);
265        cmd = SD_CMD_CMD6_SWITCH | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
266                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1B;
267        if (mmccmd(cmd, arg, resp) == -1)
268                return(-1);
269        while (!(MMC1_REG(SD_STAT) & SD_STAT_TC));
270
271        /* Wait while CMD6 is still in effect, i.e. while eMMC is not in Transfer State */
272        do {
273                arg = (mmcrca << 16) & 0xFFFF0000;
274                cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
275                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
276                if (mmccmd(cmd, arg, resp) == -1)
277                        return(-1);
278        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER);
279
280        /* Configure the MMC1 controller to use an 8-bit data width */
281        MMC1_REG(SD_CON) |= SD_CON_DW8_8BIT;
282
283        /* Send CMD6 to change to high-speed mode */
284        arg = 0x03B90100;
285        cmd = SD_CMD_CMD6_SWITCH | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
286                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1B;
287        if (mmccmd(cmd, arg, resp) == -1)
288                return(-1);
289        while (!(MMC1_REG(SD_STAT) & SD_STAT_TC));
290
291        /* Wait while CMD6 is still in effect, i.e. while eMMC is not in Transfer State */
292        do {
293                arg = (mmcrca << 16) & 0xFFFF0000;
294                cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
295                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
296                if (mmccmd(cmd, arg, resp) == -1)
297                        return(-1);
298        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER);
299
300        /* Change the clock frequency to 48 MHz and set the DTO to the maximum value setting */
301        MMC1_REG(SD_SYSCTL) &= ~SD_SYSCTL_DTO;
302        MMC1_REG(SD_SYSCTL) |= SD_SYSCTL_DTO_TCF_2_27;
303        MMC1_REG(SD_SYSCTL) = (MMC1_REG(SD_SYSCTL) & ~SD_SYSCTL_CLKD) | (2 << 6);
304
305        /* Wait for clock to stabilize */
306        while ((MMC1_REG(SD_SYSCTL) & SD_SYSCTL_ICS) != SD_SYSCTL_ICS);
307
308        /* Put the eMMC into Stand-by State */
309        arg = 0x00000000;
310        cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
311                SD_CMD_CICE_DISABLE | SD_CMD_CCCE_DISABLE | SD_CMD_RSP_TYPE_NO_RESPONSE;
312        if (mmccmd(cmd, arg, resp) == -1)
313                return(-1);
314
315        /* Wait for the eMMC to enter Stand-by State */
316        do {
317                arg = (mmcrca << 16) & 0xFFFF0000;
318                cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
319                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
320                if (mmccmd(cmd, arg, resp) == -1)
321                        return(-1);
322        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_STANDBY);
323
324        return(0);
325}
326
327int
328mmcRead(int interface, char *buf, int blknum, int blkcnt)
329{
330        uint32_t cmd, arg, resp[4];
331        uint32_t *wordptr = (uint32_t *) buf;
332        int byteindex;
333
334        /* Get the SD card's status via CMD13 */
335        arg = (mmcrca << 16) & 0xFFFF0000;
336        cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
337                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
338        if (mmccmd(cmd, arg, resp) == -1)
339                return(-1);
340
341        /* Ensure that the card is in Transfer State before proceeding */
342        if ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER) {
343                arg = (mmcrca << 16) & 0xFFFF0000;
344                cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL |
345                        SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE |
346                        SD_CMD_RSP_TYPE_R1B;
347                if (mmccmd(cmd, arg, resp) == -1)
348                        return(-1);
349
350                /* Wait for the SD card to enter Transfer State */
351                do {
352                        arg = (mmcrca << 16) & 0xFFFF0000;
353                        cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL |
354                                SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE |
355                                SD_CMD_RSP_TYPE_R1;
356                        if (mmccmd(cmd, arg, resp) == -1)
357                                return(-1);
358                } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER);
359        }
360
361        /* Set the block length and the number of blocks to read */
362        MMC1_REG(SD_BLK) = 0x200 | (blkcnt << 16);
363        /* Read multiple blocks via CMD18 */
364        arg = blknum;
365        cmd = SD_CMD_CMD18_READ_MULTIPLE_BLOCK | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_DATA_PRESENT |
366                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1 | SD_CMD_MSBS_MULTIPLE |
367                SD_CMD_DDIR_READ | SD_CMD_ACEN_CMD12_ENABLE | SD_CMD_BCE_ENABLE;
368        if (mmccmd(cmd, arg, resp) == -1)
369                return(-1);
370
371        /* Check the data buffer to see if there is data to be read */
372        do {
373                while (!(MMC1_REG(SD_STAT) & SD_STAT_BRR));
374
375                /* Clear the BRR status bit in SD_STAT */
376                MMC1_REG(SD_STAT) |= SD_STAT_BRR;
377
378                for (byteindex = 0; byteindex < (0x200 / 4); byteindex++) {
379                        *wordptr = MMC1_REG(SD_DATA);
380                        wordptr++;
381                }
382        } while (!(MMC1_REG(SD_STAT) & SD_STAT_TC));
383
384        /* Put the eMMC into Stand-by State */
385        arg = 0;
386        cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
387                SD_CMD_CICE_DISABLE | SD_CMD_CCCE_DISABLE | SD_CMD_RSP_TYPE_NO_RESPONSE;
388        if (mmccmd(cmd, arg, resp) == -1)
389                return(-1);
390
391        /* Wait for the eMMC to enter Stand-by State */
392        do {
393                arg = (mmcrca << 16) & 0xFFFF0000;
394                cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
395                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
396                if (mmccmd(cmd, arg, resp) == -1)
397                        return(-1);
398        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_STANDBY);
399
400        return(0);
401}
402
403int
404mmcWrite(int interface, char *buf, int blknum, int blkcnt)
405{
406        uint32_t cmd, arg, resp[4];
407        uint32_t *wordptr = (uint32_t *) buf;
408        int byteindex;
409
410        /* Get the eMMC status by sending CMD13 */
411        arg = (mmcrca << 16) & 0xFFFF0000;
412        cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
413                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
414        if (mmccmd(cmd, arg, resp) == -1)
415                return(-1);
416
417        /* Ensure that the eMMC is in the Transfer State before proceeding */
418        if ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER) {
419                arg = (mmcrca << 16) & 0xFFFF0000;
420                cmd  = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL |
421                        SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE |
422                        SD_CMD_RSP_TYPE_R1B;
423                if (mmccmd(cmd, arg, resp) == -1)
424                        return(-1);
425
426                /* Wait for eMMC to enter Transfer State */
427                do {
428                        arg = (mmcrca << 16) & 0xFFFF0000;
429                        cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL |
430                                SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE |
431                                SD_CMD_RSP_TYPE_R1;
432                        if (mmccmd(cmd, arg, resp) == -1)
433                                return(-1);
434                } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER);
435        }
436
437        /* Set the block length in bytes and the number of blocks to write to the SD card */
438        MMC1_REG(SD_BLK) = 0x200 | (blkcnt << 16);
439        /* Send CMD25, that is write the number of blocks specified in 'blkcount' from 'buf' to the
440         * location that is 512 byte aligned in the SD card specified by the block number 'blknum'
441         */
442        arg = blknum;
443        cmd = SD_CMD_CMD25_WRITE_MULTIPLE_BLOCK | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_DATA_PRESENT |
444                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1 | SD_CMD_MSBS_MULTIPLE |
445                SD_CMD_DDIR_WRITE | SD_CMD_ACEN_CMD12_ENABLE | SD_CMD_BCE_ENABLE;
446        if (mmccmd(cmd, arg, resp) == -1)
447                return(-1);
448
449        /* Write the data */
450        do {
451                /* Wait until data is ready to be written */
452                while (!(MMC1_REG(SD_STAT) & (SD_STAT_BWR | SD_STAT_TC)));
453
454                if (MMC1_REG(SD_STAT) & SD_STAT_TC)
455                        break;
456
457                /* Clear the BWR status bit in SD_STAT */
458                MMC1_REG(SD_STAT) |= SD_STAT_BWR;
459
460                for (byteindex = 0; byteindex < (0x200 / 4); byteindex++)
461                        MMC1_REG(SD_DATA) = *wordptr++;
462        } while (!(MMC1_REG(SD_STAT) & SD_STAT_TC));
463
464        /* Put the eMMC into Stand-by State */
465        arg = 0x00000000;
466        cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
467                SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_NO_RESPONSE;
468        if (mmccmd(cmd, arg, resp) == -1)
469                return(-1);
470
471        /* Wait for eMMC to enter Stand-by State */
472        do {
473                arg = (mmcrca << 16) & 0xFFFF0000;
474                cmd  = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT |
475                        SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1;
476                if (mmccmd(cmd, arg, resp) == -1)
477                        return(-1);
478        } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_STANDBY);
479
480        return(0);
481}
482
483int
484mmcInstalled(int interface)
485{
486        return(1);
487}
Note: See TracBrowser for help on using the repository browser.