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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
Index: firmware/export/sd.h
===================================================================
--- firmware/export/sd.h	(revision 22843)
+++ firmware/export/sd.h	(working copy)
@@ -97,6 +97,7 @@
 #define SD_ERASE                38
 #define SD_APP_OP_COND          41
 #define SD_LOCK_UNLOCK          42
+#define SD_SET_CLR_CARD_DETECT  42  /* acmd42 */
 #define SD_SEND_SCR             51  /* acmd51 */
 #define SD_APP_CMD              55

Index: firmware/target/arm/as3525/pcm-as3525.c
===================================================================
--- firmware/target/arm/as3525/pcm-as3525.c	(revision 22843)
+++ firmware/target/arm/as3525/pcm-as3525.c	(working copy)
@@ -71,8 +71,9 @@
     CGU_AUDIO |= (1<<11);

     clean_dcache_range((void*)addr, size);  /* force write back */
+         /* OF use transfers of 4 * 32 bits words on memory, i2sin, i2sout */
     dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT,
-                DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1,
+                DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S4,
                 dma_callback);
 }

Index: firmware/target/arm/as3525/system-as3525.c
===================================================================
--- firmware/target/arm/as3525/system-as3525.c	(revision 22843)
+++ firmware/target/arm/as3525/system-as3525.c	(working copy)
@@ -257,8 +257,8 @@
         CCU_SRL = CCU_SRL_MAGIC_NUMBER;
     CCU_SRC = CCU_SRL = 0;

-    CCU_SCON = 1; /* AHB master's priority configuration :
-                     TIC (Test Interface Controller) > DMA > USB > IDE > ARM */
+ //   CCU_SCON = 1; /* AHB master's priority configuration :
+ //                    TIC (Test Interface Controller) > DMA > USB > IDE > ARM */

     CGU_PROC = 0;           /* fclk 24 MHz */
     CGU_PERI &= ~0x7f;      /* pclk 24 MHz */
Index: firmware/target/arm/as3525/ata_sd_as3525.c
===================================================================
--- firmware/target/arm/as3525/ata_sd_as3525.c	(revision 22843)
+++ firmware/target/arm/as3525/ata_sd_as3525.c	(working copy)
@@ -95,6 +95,7 @@
 #endif
 };

+static int sd_wait_for_state(const int drive, unsigned int state);
 static int sd_select_bank(signed char bank);
 static int sd_init_card(const int drive);
 static void init_pl180_controller(const int drive);
@@ -245,6 +246,7 @@
     unsigned long response;
     long init_timeout;
     bool sdhc;
+    bool hscard = false;
     unsigned long temp_reg[4];
     int i;

@@ -308,21 +310,14 @@
     if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
         return -9;

-    if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
-        return -10;
+    /*  Check card for HS capable and if so switch to HS  */
+     if(card_info[drive].speed > 125000)
+     {
+         hscard = true;
+         if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL))
+             return -90;
+     }

-    if(!send_cmd(drive, SD_SET_BUS_WIDTH, card_info[drive].rca | 2, MCI_ARG, NULL))
-        return -11;
-
-    if(!send_cmd(drive, SD_SET_BLOCKLEN, card_info[drive].blocksize, MCI_ARG,
-                 NULL))
-        return -12;
-
-    card_info[drive].initialized = 1;
-
-    MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed for controller clock */
-    mci_delay();
-
     /*
      * enable bank switching 
      * without issuing this command, we only have access to 1/4 of the blocks
@@ -336,6 +331,32 @@
             return ret - 13;
     }

+    card_info[drive].initialized = 1;
+
+    if(drive)
+    {
+        if(sd_wait_for_state(drive, SD_TRAN) < 0)
+            return -120;
+
+        if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
+            return -10;
+
+        if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_ARG, NULL))
+            return -11;
+
+        if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
+            return -100;
+
+        if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_ARG, NULL))
+            return -110;
+
+        MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS; //(drive? MCI_CLOCK_WIDEBUS: 0); /* full speed for controller clock */
+        mci_delay();
+    }
+
+
+
+
     return 0;
 }

@@ -464,7 +485,7 @@

     MCI_SELECT(drive) = 0;

-    MCI_CLOCK(drive) = MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV;
+    MCI_CLOCK(drive) = MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS;
     mci_delay();
 }

@@ -712,7 +733,7 @@
             ret -= 3*20;
             goto sd_transfer_error;
         }
-
+                     /* OF uses transfers of 8 * 32 bits words on SD */
         if(write)
             dma_enable_channel(0, dma_buf, MCI_FIFO(drive),
                 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT,
@@ -737,9 +758,10 @@
         wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);

         /* Higher speed class cards need a write delay here for some reason */
+
         if((drive == SD_SLOT_AS3525) && write)
         {
-            int delay = 3500;
+            int delay = 0x3500;
             while(delay--)  asm volatile ("nop\n");
         }

Index: firmware/target/arm/as3525/dma-pl081.c
===================================================================
--- firmware/target/arm/as3525/dma-pl081.c	(revision 22843)
+++ firmware/target/arm/as3525/dma-pl081.c	(working copy)
@@ -33,28 +33,30 @@
     if(++dma_used == 1)
     {
         CGU_PERI |= CGU_DMA_CLOCK_ENABLE;
-        DMAC_CONFIGURATION |= (1<<0);
-    }
+        DMAC_CONFIGURATION |= (1<<0);        /* SMDMAC enable  */
+    } 
 }

 void dma_release(void)
 {
     if(--dma_used == 0)
     {
-        DMAC_CONFIGURATION &= ~(1<<0);
+        DMAC_CONFIGURATION &= ~(1<<0);      /*  SMDMAC  disable (save power)  */
         CGU_PERI &= ~CGU_DMA_CLOCK_ENABLE;
     }
 }

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

 inline void dma_disable_channel(int channel)
 {
-    DMAC_CH_CONFIGURATION(channel) &= ~(1<<0);
+    DMAC_CH_CONFIGURATION(channel) |= (1<<19);           /*  Set Halt Bit    */
+    while(DMAC_CH_CONFIGURATION(channel) & (1<<18));     /*  Poll Active Bit */
+    DMAC_CH_CONFIGURATION(channel) &= ~(1<<0);           /*  Clear Enable Bit*/
 }

 void dma_enable_channel(int channel, void *src, void *dst, int peri,
@@ -63,37 +65,45 @@
 {
     dma_callback[channel] = callback;

-    int control = 0;
+    /* clear any pending interrupts leftover from previous operations */
+    DMAC_INT_TC_CLEAR  = (1<<channel);
+    DMAC_INT_ERR_CLEAR = (1<<channel);

     DMAC_CH_SRC_ADDR(channel) = (int)src;
     DMAC_CH_DST_ADDR(channel) = (int)dst;

     DMAC_CH_LLI(channel) = 0;    /* we use contigous memory, so don't use the LLI */

-    /* specify address increment */
-    if(src_inc)
-        control |= (1<<26);
-
-    if(dst_inc)
-        control |= (1<<27);
-
+    /**  Channel Control Register */
     /* OF use transfers of 4 * 32 bits words on memory, i2sin, i2sout */
     /* OF use transfers of 8 * 32 bits words on SD */
+    DMAC_CH_CONTROL(channel) = (
+          (1<<31)                 /* current LLI triggers terminal count interrupt */
+                                  /* Protection bits */
+        | (0<<30)                     /* cacheable  = 1,  non = 0 */
+        | (1<<29)                     /* bufferable = 1,  non = 0 */
+        | (1<<28)                     /* privileged = 1, user = 0 */
+        | (dst_inc? (1<<27): 0)   /* specify address increment */
+        | (src_inc? (1<<26): 0)   /* specify address increment */
+        /* [25:24] */             /* undefined  */
+        | (2<<21)                 /* dst width = word, 32bit */
+        | (2<<18)                 /* src width = word, 32bit */
+        | (nwords<<15)            /* dst size  */
+        | (nwords<<12)            /* src size  */
+        | ((size & 0x7ff)<<0)     /* transfer size */
+        );

-    control |= (2<<21) | (2<<18);  /* dst/src width = word, 32bit */
-    control |= (nwords<<15) | (nwords<<12);  /* dst/src size  */
-    control |= (size & 0x7ff);     /* transfer size */
-
-    control |= (1<<31); /* current LLI is expected to trigger terminal count interrupt */
-
-    DMAC_CH_CONTROL(channel) = control;
-
+    /**  Channel Config Register  */
     /* we set the same peripheral as source and destination because we always
      * use memory-to-peripheral or peripheral-to-memory transfers */
     DMAC_CH_CONFIGURATION(channel) =
-        (flow_controller<<11)   /* flow controller is peripheral */
+       /* [31:19] */            /* Read undefined. Write as zero  */
+          (0<<18)               /* Halt Bit    */
+        | (0<<17)               /* Active Bit  */
+        | (0<<16)               /* Lock Bit    */
         | (1<<15)               /* terminal count interrupt mask */
         | (1<<14)               /* interrupt error mask */
+        | (flow_controller<<11) /* flow controller is peripheral */
         | (peri<<6)             /* dst peripheral */
         | (peri<<1)             /* src peripheral */
         | (1<<0)                /* enable channel */