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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 firmware/target/arm/as3525/ata_sd_as3525.c |   39 +++++++++++++--------------
 firmware/target/arm/as3525/dma-pl081.c     |    2 +-
 2 files changed, 20 insertions(+), 21 deletions(-)


diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index c792946..79e8fac 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -248,6 +248,11 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
     return false;
 }

+#define MCI_FULLSPEED        (MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS)
+#define MCI_HALFSPEED        (MCI_CLOCK_ENABLE)
+#define MCI_QUARTERSPEED     (MCI_CLOCK_ENABLE | 1)
+#define MCI_IDENTSPEED       (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV)
+
 static int sd_init_card(const int drive)
 {
     unsigned long response;
@@ -257,13 +262,13 @@ static int sd_init_card(const int drive)
     int i;


-    /* 100 - 400kHz clock required for Identification Mode  */
-    MCI_CLOCK(drive) = (MCI_CLOCK(drive) & 0xf00) | AS3525_SD_IDENT_DIV;
-
+    /*   MCLCK on and set to 400kHz ident frequency  */
+    MCI_CLOCK(drive) = MCI_IDENTSPEED;
+    mci_delay();

+    /* 100 - 400kHz clock required for Identification Mode  */
     /*  Start of Card Identification Mode ************************************/

-
     /* CMD0 Go Idle  */
     if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL))
         return -1;
@@ -306,13 +311,10 @@ static int sd_init_card(const int drive)
                 &card_info[drive].rca))
         return -4;

-
     /*  End of Card Identification Mode   ************************************/

-
-    /* full speed for controller clock  MCICLK = MCLK = PCLK = 62 MHz */
-    MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS;   /*  FIXME: 50 MHz is spec limit  */
-    mci_delay();
+    /* Boost MCICLK to operating speed */
+    MCI_CLOCK(drive) = (sd_v2 ? MCI_HALFSPEED : MCI_QUARTERSPEED);

 #ifdef HAVE_MULTIDRIVE
     /* Try to switch V2 cards to HS timings, non HS seem to ignore this */
@@ -489,9 +491,6 @@ static void init_pl180_controller(const int drive)
     mci_delay();

     MCI_SELECT(drive) = 0;
-
-    MCI_CLOCK(drive) = MCI_CLOCK_ENABLE;
-    mci_delay();
 }

 int sd_init(void)
@@ -744,7 +743,13 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
         wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);

         /*  Wait for FIFO to empty, card may still be in PRG state for writes */
-        while(MCI_STATUS(drive) & MCI_TX_ACTIVE);
+//        while(MCI_STATUS(drive) & MCI_TX_ACTIVE);
+
+        if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_NO_FLAGS, NULL))
+        {
+            ret = -4*20;
+            goto sd_transfer_error;
+        }

         if(!transfer_error[drive])
         {
@@ -756,15 +761,9 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
             loops = 0;  /* reset errors counter */
         }
         else if(loops++ > PL180_MAX_TRANSFER_ERRORS)
-                panicf("SD transfer error : 0x%x", transfer_error[drive]);
+                panicf("SD Xfer %s err:0x%x Disk%d", (write? "write": "read"), transfer_error[drive], drive);

         last_disk_activity = current_tick;
-
-        if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_NO_FLAGS, NULL))
-        {
-            ret = -4*20;
-            goto sd_transfer_error;
-        }
     }

     ret = 0;    /* success */
diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c
index e0620dc..dfef02d 100644
--- a/firmware/target/arm/as3525/dma-pl081.c
+++ b/firmware/target/arm/as3525/dma-pl081.c
@@ -48,7 +48,7 @@ void dma_release(void)

 void dma_init(void)
 {
-    DMAC_SYNC = 0xffff; /* disable synchronisation logic */
+//    DMAC_SYNC = 0xffff; /* disable synchronisation logic */
     VIC_INT_ENABLE = INTERRUPT_DMAC;
 }