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
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index d42f7b4..122632b 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -32,8 +32,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include "as3525v2.h"
-#include "pl081.h"  /* DMA controller */
-#include "dma-target.h" /* DMA request lines */
+//#include "pl081.h"  /* DMA controller */
+//#include "dma-target.h" /* DMA request lines */
 #include "clock-target.h"
 #include "panic.h"
 #include "stdbool.h"
@@ -315,8 +315,8 @@
 #define MCI_FIFO        ((unsigned long *) (SD_BASE+0x100))

 #define UNALIGNED_NUM_SECTORS 10
-static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32)));   /* align on cache line size */
-static unsigned char *uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);
+//static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32)));   /* align on cache line size */
+//static unsigned char *uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);

 static void init_controller(void);
 static int sd_wait_for_state(const int drive, unsigned int state);
@@ -338,7 +338,7 @@ bool sd_enabled = false;
 #endif

 static struct wakeup transfer_completion_signal;
-static volatile bool retry;
+//static volatile bool retry;

 #if defined(HAVE_MULTIDRIVE)
 int active_card = 0;
@@ -347,6 +347,11 @@ int active_card = 0;

 static inline void mci_delay(void) { udelay(1000); }

+static unsigned irq_words;
+static uint32_t *irq_ptr;
+static bool irq_write;
+static unsigned irq_counter = 0;
+
 void INT_NAND(void)
 {
     MCI_CTRL &= ~INT_ENABLE;
@@ -355,10 +360,36 @@ void INT_NAND(void)
     MCI_RAW_STATUS = status;    /* clear status */

     if(status & MCI_DATA_ERROR)
-        retry = true;
+        //retry = true;
+        panicf("error");
+
+    if(status & MCI_INT_RXDR)
+    {
+        irq_counter++;
+        /* PIO */
+        volatile unsigned int *fifo = (volatile unsigned int*)MCI_FIFO;
+
+        if(irq_write)
+        {
+            // TODO
+        }
+        else
+        {
+            unsigned fifo_words = (MCI_STATUS << 2) >> 21;
+            /*static int x = 0;
+            if(x++ == 2) panicf("reading %d", fifo_words);*/
+            while(fifo_words--)
+            {
+                irq_words--;
+                *irq_ptr++ = *fifo;
+            }
+            if(irq_words == 0)
+                wakeup_signal(&transfer_completion_signal);
+        }
+    }

-    if( status & (MCI_INT_DTO|MCI_DATA_ERROR))
-        wakeup_signal(&transfer_completion_signal);
+    /*if(status & MCI_INT_DTO)
+        wakeup_signal(&transfer_completion_signal);*/

     MCI_CTRL |= INT_ENABLE;
 }
@@ -783,12 +814,13 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
 #endif

     last_disk_activity = current_tick;
-    dma_retain();
+    //dma_retain();

     const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;

     do
     {
+#if 0
         void *dma_buf = aligned_buffer;
         unsigned int transfer = count;
         if(transfer > UNALIGNED_NUM_SECTORS)
@@ -796,12 +828,13 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,

         if(write)
             memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE);
+#endif

         /* Interrupt handler might set this to true during transfer */
-        retry = false;
+        //retry = false;

         MCI_BLKSIZ = SD_BLOCK_SIZE;
-        MCI_BYTCNT = transfer * SD_BLOCK_SIZE;
+        MCI_BYTCNT = /*transfer*/ count * SD_BLOCK_SIZE;

         ret = sd_wait_for_state(drive, SD_TRAN);
         if (ret < 0)
@@ -817,8 +850,8 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
             goto sd_transfer_error;
         }

-        MCI_MASK |= (MCI_DATA_ERROR | MCI_INT_DTO);
-        MCI_CTRL |= DMA_ENABLE;
+        MCI_MASK |= (MCI_DATA_ERROR /*| MCI_INT_DTO*/);
+        //MCI_CTRL |= DMA_ENABLE;

         int arg = start;
         if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
@@ -827,6 +860,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
         if(!send_cmd(drive, cmd, arg, MCI_NO_RESP, NULL))
             panicf("%s multiple blocks failed", write ? "write" : "read");

+#if 0
         if(write)
             dma_enable_channel(0, dma_buf, MCI_FIFO, DMA_PERI_SD,
                 DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL);
@@ -834,9 +868,22 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
             dma_enable_channel(0, MCI_FIFO, dma_buf, DMA_PERI_SD,
                 DMAC_FLOWCTRL_PERI_PERI_TO_MEM, false, true, 0, DMA_S8, NULL);

+#else
+        irq_write = write;
+        irq_words = count * SD_BLOCK_SIZE >> 2;
+        irq_ptr = buf;
+        MCI_MASK |= MCI_INT_RXDR;
+#endif
+
+        while(irq_words != 0)
+        {
+            splashf(HZ, "%d rem. (%d)", irq_words, irq_counter);
+        }
+
         wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);

-        MCI_MASK &= ~(MCI_DATA_ERROR | MCI_INT_DTO);
+        MCI_MASK &= ~(MCI_INT_RXDR);
+        MCI_MASK &= ~(MCI_DATA_ERROR /*| MCI_INT_DTO*/);

         last_disk_activity = current_tick;

@@ -847,6 +894,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
             goto sd_transfer_error;
         }

+#if 0
         if(!retry)
         {
             if(!write)
@@ -861,10 +909,11 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
             while(MCI_CTRL & (FIFO_RESET|DMA_RESET))
                 ;
         }
+#endif

-    } while(retry || count);
+    } while(/*retry || count*/ 0);

-    dma_release();
+    //dma_release();

 #ifdef HAVE_MULTIDRIVE
     /* CMD lines are separate, not common, so we need to actively deselect */