1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 firmware/target/arm/as3525/ata_sd_as3525.c |   28 +++++++++++++++++++++-------
 1 files changed, 21 insertions(+), 7 deletions(-)


diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 43c1a37..21cc9a2 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -336,9 +336,6 @@ static int sd_init_card(const int drive)
     }
 #endif /*  HAVE_MULTIDRIVE  */

-    /* Boost MCICLK to operating speed */ /*FIXME: v1 at 31 MHz still too high*/
-    MCI_CLOCK(drive) = (sd_v2 ? MCI_HALFSPEED : MCI_HALFSPEED);
-
     /* CMD9 send CSD */
     if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca,
                  MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg))
@@ -349,6 +346,14 @@ static int sd_init_card(const int drive)

     sd_parse_csd(&card_info[drive]);

+    /* Boost MCICLK to operating speed */
+    if(!drive)
+        MCI_CLOCK(drive) = MCI_QUARTERSPEED;  /* MCICLK = PCLK/4 = 15.5MHz  */
+    else
+        /* MCICLK = PCLK/2 = 31MHz or PCLK/4 = 15.5 Mhz */
+        MCI_CLOCK(drive) = ((card_info[drive].speed == 50000000) ?
+                                              MCI_HALFSPEED : MCI_QUARTERSPEED);
+
     /*  CMD7 w/rca: Select card to put it in TRAN state */
     if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
         return -10;
@@ -619,6 +624,7 @@ static int sd_select_bank(signed char bank)
                                 (1<<3) /* DMA */                |
                                 (9<<4) /* 2^9 = 512 */ ;

+        /* Wakup signal comes from NAND/MCIO isr on MCI_ERROR | MCI_DATA_END  */
         wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);

         /*  Wait for FIFO to empty, card may still be in PRG state  */
@@ -697,16 +703,17 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
                 transfer = BLOCKS_PER_BANK - bank_start;
         }

+        /* Set bank_start to the correct unit (blocks or bytes) */
+        if(!(card_info[drive].ocr & (1<<30)))   /* not SDHC */
+            bank_start *= SD_BLOCK_SIZE;
+
         dma_buf = aligned_buffer;
         if(transfer > UNALIGNED_NUM_SECTORS)
             transfer = UNALIGNED_NUM_SECTORS;
+
         if(write)
             memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE);

-        /* Set bank_start to the correct unit (blocks or bytes) */
-        if(!(card_info[drive].ocr & (1<<30)))   /* not SDHC */
-            bank_start *= SD_BLOCK_SIZE;
-
         ret = sd_wait_for_state(drive, SD_TRAN);
         if (ret < 0)
         {
@@ -721,9 +728,15 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
         }

         if(write)
+        {
             dma_enable_channel(0, dma_buf, MCI_FIFO(drive),
                 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT,
                 DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL);
+
+            /* writes need a small delay here to prevent data crc failures */
+            int write_delay = 125;
+            while(write_delay--);
+        }
         else
             dma_enable_channel(0, MCI_FIFO(drive), dma_buf,
                 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT,
@@ -740,6 +753,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
                                 (1<<3) /* DMA */                        |
                                 (9<<4) /* 2^9 = 512 */ ;

+        /* Wakup signal comes from NAND/MCIO isr on MCI_ERROR | MCI_DATA_END  */
         wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);

         /*  Wait for FIFO to empty, card may still be in PRG state for writes */