summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/pl180.h15
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c256
2 files changed, 159 insertions, 112 deletions
diff --git a/firmware/export/pl180.h b/firmware/export/pl180.h
index 98993cc244..4c439fb431 100644
--- a/firmware/export/pl180.h
+++ b/firmware/export/pl180.h
@@ -22,6 +22,8 @@
22/* ARM PrimeCell PL180 SD/MMC controller */ 22/* ARM PrimeCell PL180 SD/MMC controller */
23 23
24/* MCIStatus bits */ 24/* MCIStatus bits */
25
26/* bits 10:0 can be cleared by a write in MCIClear */
25#define MCI_CMD_CRC_FAIL (1<<0) 27#define MCI_CMD_CRC_FAIL (1<<0)
26#define MCI_DATA_CRC_FAIL (1<<1) 28#define MCI_DATA_CRC_FAIL (1<<1)
27#define MCI_CMD_TIMEOUT (1<<2) 29#define MCI_CMD_TIMEOUT (1<<2)
@@ -33,7 +35,18 @@
33#define MCI_DATA_END (1<<8) 35#define MCI_DATA_END (1<<8)
34#define MCI_START_BIT_ERR (1<<9) 36#define MCI_START_BIT_ERR (1<<9)
35#define MCI_DATA_BLOCK_END (1<<10) 37#define MCI_DATA_BLOCK_END (1<<10)
36#define MCI_CMD_ACTIVE (1<<11) 38/* bits 21:11 are only cleared by the hardware logic */
39#define MCI_CMD_ACTIVE (1<<11)
40#define MCI_TX_ACTIVE (1<<12)
41#define MCI_RX_ACTIVE (1<<13)
42#define MCI_TX_FIFO_HALF_EMPTY (1<<14)
43#define MCI_RX_FIFO_HALF_FULL (1<<15)
44#define MCI_TX_FIFO_FULL (1<<16)
45#define MCI_RX_FIFO_FULL (1<<17)
46#define MCI_TX_FIFO_EMPTY (1<<18)
47#define MCI_RX_FIFO_EMPTY (1<<19)
48#define MCI_TX_DATA_AVAIL (1<<20)
49#define MCI_RX_DATA_AVAIL (1<<21)
37 50
38 51
39/* MCIPower bits */ 52/* MCIPower bits */
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 9405832595..bc2866219a 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -28,7 +28,9 @@
28#include "hotswap.h" 28#include "hotswap.h"
29#include "system.h" 29#include "system.h"
30#include "cpu.h" 30#include "cpu.h"
31#include <stdio.h>
31#include <stdlib.h> 32#include <stdlib.h>
33#include <string.h>
32#include "as3525.h" 34#include "as3525.h"
33#include "pl180.h" 35#include "pl180.h"
34#include "panic.h" 36#include "panic.h"
@@ -41,36 +43,36 @@
41#endif 43#endif
42 44
43/* command flags */ 45/* command flags */
44#define MMC_NO_FLAGS (0<<0) 46#define MCI_NO_FLAGS (0<<0)
45#define MMC_RESP (1<<0) 47#define MCI_RESP (1<<0)
46#define MMC_LONG_RESP (1<<1) 48#define MCI_LONG_RESP (1<<1)
47#define MMC_ARG (1<<2) 49#define MCI_ARG (1<<2)
48 50
49/* ARM PL180 registers */ 51/* ARM PL180 registers */
50#define MMC_POWER(i) (*(volatile unsigned char *) (pl180_base[i]+0x00)) 52#define MCI_POWER(i) (*(volatile unsigned char *) (pl180_base[i]+0x00))
51#define MMC_CLOCK(i) (*(volatile unsigned long *) (pl180_base[i]+0x04)) 53#define MCI_CLOCK(i) (*(volatile unsigned long *) (pl180_base[i]+0x04))
52#define MMC_ARGUMENT(i) (*(volatile unsigned long *) (pl180_base[i]+0x08)) 54#define MCI_ARGUMENT(i) (*(volatile unsigned long *) (pl180_base[i]+0x08))
53#define MMC_COMMAND(i) (*(volatile unsigned long *) (pl180_base[i]+0x0C)) 55#define MCI_COMMAND(i) (*(volatile unsigned long *) (pl180_base[i]+0x0C))
54#define MMC_RESPCMD(i) (*(volatile unsigned long *) (pl180_base[i]+0x10)) 56#define MCI_RESPCMD(i) (*(volatile unsigned long *) (pl180_base[i]+0x10))
55#define MMC_RESP0(i) (*(volatile unsigned long *) (pl180_base[i]+0x14)) 57#define MCI_RESP0(i) (*(volatile unsigned long *) (pl180_base[i]+0x14))
56#define MMC_RESP1(i) (*(volatile unsigned long *) (pl180_base[i]+0x18)) 58#define MCI_RESP1(i) (*(volatile unsigned long *) (pl180_base[i]+0x18))
57#define MMC_RESP2(i) (*(volatile unsigned long *) (pl180_base[i]+0x1C)) 59#define MCI_RESP2(i) (*(volatile unsigned long *) (pl180_base[i]+0x1C))
58#define MMC_RESP3(i) (*(volatile unsigned long *) (pl180_base[i]+0x20)) 60#define MCI_RESP3(i) (*(volatile unsigned long *) (pl180_base[i]+0x20))
59#define MMC_DATA_TIMER(i) (*(volatile unsigned long *) (pl180_base[i]+0x24)) 61#define MCI_DATA_TIMER(i) (*(volatile unsigned long *) (pl180_base[i]+0x24))
60#define MMC_DATA_LENGTH(i) (*(volatile unsigned short*) (pl180_base[i]+0x28)) 62#define MCI_DATA_LENGTH(i) (*(volatile unsigned short*) (pl180_base[i]+0x28))
61#define MMC_DATA_CTRL(i) (*(volatile unsigned char *) (pl180_base[i]+0x2C)) 63#define MCI_DATA_CTRL(i) (*(volatile unsigned char *) (pl180_base[i]+0x2C))
62#define MMC_DATA_CNT(i) (*(volatile unsigned short*) (pl180_base[i]+0x30)) 64#define MCI_DATA_CNT(i) (*(volatile unsigned short*) (pl180_base[i]+0x30))
63#define MMC_STATUS(i) (*(volatile unsigned long *) (pl180_base[i]+0x34)) 65#define MCI_STATUS(i) (*(volatile unsigned long *) (pl180_base[i]+0x34))
64#define MMC_CLEAR(i) (*(volatile unsigned long *) (pl180_base[i]+0x38)) 66#define MCI_CLEAR(i) (*(volatile unsigned long *) (pl180_base[i]+0x38))
65#define MMC_MASK0(i) (*(volatile unsigned long *) (pl180_base[i]+0x3C)) 67#define MCI_MASK0(i) (*(volatile unsigned long *) (pl180_base[i]+0x3C))
66#define MMC_MASK1(i) (*(volatile unsigned long *) (pl180_base[i]+0x40)) 68#define MCI_MASK1(i) (*(volatile unsigned long *) (pl180_base[i]+0x40))
67#define MMC_SELECT(i) (*(volatile unsigned long *) (pl180_base[i]+0x44)) 69#define MCI_SELECT(i) (*(volatile unsigned long *) (pl180_base[i]+0x44))
68#define MMC_FIFO_CNT(i) (*(volatile unsigned long *) (pl180_base[i]+0x48)) 70#define MCI_FIFO_CNT(i) (*(volatile unsigned long *) (pl180_base[i]+0x48))
69 71
70#define MMC_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80)) 72#define MCI_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80))
71/* volumes */ 73/* volumes */
72#define NAND_AS3525 0 74#define NAND_AS3525 0 /* embedded SD card */
73#define SD_AS3525 1 75#define SD_AS3525 1 /* SD slot if present */
74 76
75static const int pl180_base[NUM_VOLUMES] = { 77static const int pl180_base[NUM_VOLUMES] = {
76 NAND_FLASH_BASE 78 NAND_FLASH_BASE
@@ -87,11 +89,10 @@ static tSDCardInfo card_info[NUM_VOLUMES];
87/* for compatibility */ 89/* for compatibility */
88static long last_disk_activity = -1; 90static long last_disk_activity = -1;
89 91
90#define MIN_YIELD_PERIOD 1000 92#define MIN_YIELD_PERIOD 5 /* ticks */
91static long next_yield = 0; 93static long next_yield = 0;
92 94
93/* Shoot for around 75% usage */ 95static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
94static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
95static const char sd_thread_name[] = "ata/sd"; 96static const char sd_thread_name[] = "ata/sd";
96static struct mutex sd_mtx SHAREDBSS_ATTR; 97static struct mutex sd_mtx SHAREDBSS_ATTR;
97static struct event_queue sd_queue; 98static struct event_queue sd_queue;
@@ -100,14 +101,14 @@ static inline void mci_delay(void) { int i = 0xffff; while(i--) ; }
100 101
101static void mci_set_clock_divider(const int drive, int divider) 102static void mci_set_clock_divider(const int drive, int divider)
102{ 103{
103 int clock = MMC_CLOCK(drive); 104 int clock = MCI_CLOCK(drive);
104 105
105 if(divider > 1) 106 if(divider > 1)
106 { 107 {
107 /* use divide logic */ 108 /* use divide logic */
108 clock &= ~MCI_CLOCK_BYPASS; 109 clock &= ~MCI_CLOCK_BYPASS;
109 110
110 /* convert divider to MMC_CLOCK logic */ 111 /* convert divider to MCI_CLOCK logic */
111 divider = (divider/2) - 1; 112 divider = (divider/2) - 1;
112 if(divider >= 256) 113 if(divider >= 256)
113 divider = 255; 114 divider = 255;
@@ -119,7 +120,7 @@ static void mci_set_clock_divider(const int drive, int divider)
119 divider = 0; 120 divider = 0;
120 } 121 }
121 122
122 MMC_CLOCK(drive) = clock | divider; 123 MCI_CLOCK(drive) = clock | divider;
123 124
124 mci_delay(); 125 mci_delay();
125} 126}
@@ -129,51 +130,51 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
129{ 130{
130 int val, status; 131 int val, status;
131 132
132 while(MMC_STATUS(drive) & MCI_CMD_ACTIVE); 133 while(MCI_STATUS(drive) & MCI_CMD_ACTIVE);
133 134
134 if(MMC_COMMAND(drive) & MCI_COMMAND_ENABLE) /* clears existing command */ 135 if(MCI_COMMAND(drive) & MCI_COMMAND_ENABLE) /* clears existing command */
135 { 136 {
136 MMC_COMMAND(drive) = 0; 137 MCI_COMMAND(drive) = 0;
137 mci_delay(); 138 mci_delay();
138 } 139 }
139 140
140 val = cmd | MCI_COMMAND_ENABLE; 141 val = cmd | MCI_COMMAND_ENABLE;
141 if(flags & MMC_RESP) 142 if(flags & MCI_RESP)
142 { 143 {
143 val |= MCI_COMMAND_RESPONSE; 144 val |= MCI_COMMAND_RESPONSE;
144 if(flags & MMC_LONG_RESP) 145 if(flags & MCI_LONG_RESP)
145 val |= MCI_COMMAND_LONG_RESPONSE; 146 val |= MCI_COMMAND_LONG_RESPONSE;
146 } 147 }
147 148
148 MMC_CLEAR(drive) = 0x7ff; 149 MCI_CLEAR(drive) = 0x7ff;
149 150
150 MMC_ARGUMENT(drive) = (flags & MMC_ARG) ? arg : 0; 151 MCI_ARGUMENT(drive) = (flags & MCI_ARG) ? arg : 0;
151 MMC_COMMAND(drive) = val; 152 MCI_COMMAND(drive) = val;
152 153
153 while(MMC_STATUS(drive) & MCI_CMD_ACTIVE); /* wait for cmd completion */ 154 while(MCI_STATUS(drive) & MCI_CMD_ACTIVE); /* wait for cmd completion */
154 155
155 MMC_COMMAND(drive) = 0; 156 MCI_COMMAND(drive) = 0;
156 MMC_ARGUMENT(drive) = ~0; 157 MCI_ARGUMENT(drive) = ~0;
157 158
158 status = MMC_STATUS(drive); 159 status = MCI_STATUS(drive);
159 MMC_CLEAR(drive) = 0x7ff; 160 MCI_CLEAR(drive) = 0x7ff;
160 161
161 if(flags & MMC_RESP) 162 if(flags & MCI_RESP)
162 { 163 {
163 if(status & MCI_CMD_TIMEOUT) 164 if(status & MCI_CMD_TIMEOUT)
164 return false; 165 return false;
165 else if(status & (MCI_CMD_CRC_FAIL /* FIXME? */ | MCI_CMD_RESP_END)) 166 else if(status & (MCI_CMD_CRC_FAIL /* FIXME? */ | MCI_CMD_RESP_END))
166 { /* resp received */ 167 { /* resp received */
167 if(flags & MMC_LONG_RESP) 168 if(flags & MCI_LONG_RESP)
168 { 169 {
169 /* store the response in little endian order for the words */ 170 /* store the response in little endian order for the words */
170 response[0] = MMC_RESP3(drive); 171 response[0] = MCI_RESP3(drive);
171 response[1] = MMC_RESP2(drive); 172 response[1] = MCI_RESP2(drive);
172 response[2] = MMC_RESP1(drive); 173 response[2] = MCI_RESP1(drive);
173 response[3] = MMC_RESP0(drive); 174 response[3] = MCI_RESP0(drive);
174 } 175 }
175 else 176 else
176 response[0] = MMC_RESP0(drive); 177 response[0] = MCI_RESP0(drive);
177 return true; 178 return true;
178 } 179 }
179 } 180 }
@@ -191,13 +192,13 @@ static int sd_init_card(const int drive)
191 int max_tries = 100; /* max acmd41 attemps */ 192 int max_tries = 100; /* max acmd41 attemps */
192 bool sdhc; 193 bool sdhc;
193 194
194 if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MMC_NO_FLAGS, NULL)) 195 if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL))
195 return -1; 196 return -1;
196 197
197 mci_delay(); 198 mci_delay();
198 199
199 sdhc = false; 200 sdhc = false;
200 if(send_cmd(drive, SD_SEND_IF_COND, 0x1AA, MMC_RESP|MMC_ARG, &response)) 201 if(send_cmd(drive, SD_SEND_IF_COND, 0x1AA, MCI_RESP|MCI_ARG, &response))
201 if((response & 0xFFF) == 0x1AA) 202 if((response & 0xFFF) == 0x1AA)
202 sdhc = true; 203 sdhc = true;
203 204
@@ -205,7 +206,7 @@ static int sd_init_card(const int drive)
205 mci_delay(); 206 mci_delay();
206 207
207 /* app_cmd */ 208 /* app_cmd */
208 if( !send_cmd(drive, SD_APP_CMD, 0, MMC_RESP|MMC_ARG, &response) || 209 if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) ||
209 !(response & (1<<5)) ) 210 !(response & (1<<5)) )
210 { 211 {
211 return -2; 212 return -2;
@@ -213,7 +214,7 @@ static int sd_init_card(const int drive)
213 214
214 /* acmd41 */ 215 /* acmd41 */
215 if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)), 216 if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)),
216 MMC_RESP|MMC_ARG, &card_info[drive].ocr)) 217 MCI_RESP|MCI_ARG, &card_info[drive].ocr))
217 return -3; 218 return -3;
218 219
219 } while(!(card_info[drive].ocr & (1<<31)) && max_tries--); 220 } while(!(card_info[drive].ocr & (1<<31)) && max_tries--);
@@ -222,18 +223,18 @@ static int sd_init_card(const int drive)
222 return -4; 223 return -4;
223 224
224 /* send CID */ 225 /* send CID */
225 if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MMC_RESP|MMC_LONG_RESP|MMC_ARG, 226 if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG,
226 card_info[drive].cid)) 227 card_info[drive].cid))
227 return -5; 228 return -5;
228 229
229 /* send RCA */ 230 /* send RCA */
230 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MMC_RESP|MMC_ARG, 231 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG,
231 &card_info[drive].rca)) 232 &card_info[drive].rca))
232 return -6; 233 return -6;
233 234
234 /* send CSD */ 235 /* send CSD */
235 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, 236 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca,
236 MMC_RESP|MMC_LONG_RESP|MMC_ARG, card_info[drive].csd)) 237 MCI_RESP|MCI_LONG_RESP|MCI_ARG, card_info[drive].csd))
237 return -7; 238 return -7;
238 239
239 /* These calculations come from the Sandisk SD card product manual */ 240 /* These calculations come from the Sandisk SD card product manual */
@@ -259,16 +260,16 @@ static int sd_init_card(const int drive)
259 } 260 }
260#endif 261#endif
261 262
262 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MMC_ARG, NULL)) 263 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
263 return -9; 264 return -9;
264 265
265 if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MMC_ARG, NULL)) 266 if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
266 return -10; 267 return -10;
267 268
268 if(!send_cmd(drive, SD_SET_BUS_WIDTH, card_info[drive].rca | 2, MMC_ARG, NULL)) 269 if(!send_cmd(drive, SD_SET_BUS_WIDTH, card_info[drive].rca | 2, MCI_ARG, NULL))
269 return -11; 270 return -11;
270 271
271 if(!send_cmd(drive, SD_SET_BLOCKLEN, card_info[drive].block_size, MMC_ARG, 272 if(!send_cmd(drive, SD_SET_BLOCKLEN, card_info[drive].block_size, MCI_ARG,
272 NULL)) 273 NULL))
273 return -12; 274 return -12;
274 275
@@ -354,23 +355,21 @@ static void sd_thread(void)
354} 355}
355static void init_pl180_controller(const int drive) 356static void init_pl180_controller(const int drive)
356{ 357{
357#ifdef BOOTLOADER 358 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
358 MMC_COMMAND(drive) = MMC_DATA_CTRL(drive) = 0; 359 MCI_CLEAR(drive) = 0x7ff;
359 MMC_CLEAR(drive) = 0x7ff;
360 360
361 MMC_MASK0(drive) = MMC_MASK1(drive) = 0; /* disable all interrupts */ 361 MCI_MASK0(drive) = MCI_MASK1(drive) = 0; /* disable all interrupts */
362 362
363 MMC_POWER(drive) = MCI_POWER_UP|(10 /*voltage*/ << 2); /* use OF voltage */ 363 MCI_POWER(drive) = MCI_POWER_UP|(10 /*voltage*/ << 2); /* use OF voltage */
364 mci_delay(); 364 mci_delay();
365 365
366 MMC_POWER(drive) |= MCI_POWER_ON; 366 MCI_POWER(drive) |= MCI_POWER_ON;
367 mci_delay(); 367 mci_delay();
368 368
369 MMC_SELECT(drive) = 0; 369 MCI_SELECT(drive) = 0;
370 370
371 MMC_CLOCK(drive) = MCI_CLOCK_ENABLE; 371 MCI_CLOCK(drive) = MCI_CLOCK_ENABLE;
372 MMC_CLOCK(drive) &= ~MCI_CLOCK_POWERSAVE; 372 MCI_CLOCK(drive) &= ~MCI_CLOCK_POWERSAVE;
373#endif /* BOOTLOADER */
374 373
375 /* set MCLK divider */ 374 /* set MCLK divider */
376 mci_set_clock_divider(drive, 200); 375 mci_set_clock_divider(drive, 200);
@@ -380,7 +379,6 @@ int sd_init(void)
380{ 379{
381 int ret; 380 int ret;
382 381
383#ifdef BOOTLOADER /* No need to do twice the same thing */
384 CGU_IDE = (1<<7) /* AHB interface enable */ | 382 CGU_IDE = (1<<7) /* AHB interface enable */ |
385 (1<<6) /* interface enable */ | 383 (1<<6) /* interface enable */ |
386 (2<<2) /* clock didiver = 2+1 */ | 384 (2<<2) /* clock didiver = 2+1 */ |
@@ -391,16 +389,15 @@ int sd_init(void)
391 CGU_PERI |= CGU_MCI_CLOCK_ENABLE; 389 CGU_PERI |= CGU_MCI_CLOCK_ENABLE;
392#endif 390#endif
393 391
394 CCU_IO &= ~8; /* bits 3:2 = 01, xpd is SD interface */
395 CCU_IO |= 4;
396
397#endif
398 init_pl180_controller(NAND_AS3525); 392 init_pl180_controller(NAND_AS3525);
399 ret = sd_init_card(NAND_AS3525); 393 ret = sd_init_card(NAND_AS3525);
400 if(ret < 0) 394 if(ret < 0)
401 return ret; 395 return ret;
402 396
403#ifdef HAVE_MULTIVOLUME 397#ifdef HAVE_MULTIVOLUME
398 CCU_IO &= ~8; /* bits 3:2 = 01, xpd is SD interface */
399 CCU_IO |= 4;
400
404 init_pl180_controller(SD_AS3525); 401 init_pl180_controller(SD_AS3525);
405 ret = sd_init_card(SD_AS3525); 402 ret = sd_init_card(SD_AS3525);
406 if(ret < 0) 403 if(ret < 0)
@@ -451,36 +448,39 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
451 (void)start; 448 (void)start;
452 (void)count; 449 (void)count;
453 (void)buf; 450 (void)buf;
454 return 0; /* TODO */ 451 return -1; /* TODO */
455} 452}
456 453
457static bool sd_poll_status(const int drive, unsigned int trigger, long timeout) 454static int sd_poll_status(const int drive, unsigned int trigger, long timeout)
458{ 455{
459 long t = current_tick; 456 long t = current_tick;
457 //int my_next_yield =0;
458 int status;
460 459
461 while ((MMC_STATUS(drive) & trigger) == 0) 460 while (((status = MCI_STATUS(drive)) & trigger) == 0)
462 { 461 {
463 long time = current_tick; 462 long time = current_tick;
464 463
465 if (TIME_AFTER(time, next_yield)) 464/*
465 if (TIME_AFTER(time, my_next_yield))
466 { 466 {
467 long ty = current_tick; 467 long ty = current_tick;
468 yield(); 468 yield();
469 timeout += current_tick - ty; 469 timeout += current_tick - ty;
470 next_yield = ty + MIN_YIELD_PERIOD; 470 my_next_yield = ty + MIN_YIELD_PERIOD;
471 } 471 }
472 472*/
473 if (TIME_AFTER(time, t + timeout)) 473 if (TIME_AFTER(time, t + timeout))
474 return false; 474 break;
475 } 475 }
476 476
477 return true; 477 return status;
478} 478}
479 479
480static int sd_wait_for_state(const int drive, unsigned int state) 480static int sd_wait_for_state(const int drive, unsigned int state)
481{ 481{
482 unsigned int response = 0; 482 unsigned int response = 0;
483 unsigned int timeout = 0x80000; 483 unsigned int timeout = 100; /* ticks */
484 484
485 long t = current_tick; 485 long t = current_tick;
486 486
@@ -489,7 +489,7 @@ static int sd_wait_for_state(const int drive, unsigned int state)
489 long us; 489 long us;
490 490
491 if(!send_cmd(drive, SD_SEND_STATUS, card_info[drive].rca, 491 if(!send_cmd(drive, SD_SEND_STATUS, card_info[drive].rca,
492 MMC_RESP|MMC_ARG, &response)) 492 MCI_RESP|MCI_ARG, &response))
493 return -1; 493 return -1;
494 494
495 if (((response >> 9) & 0xf) == state) 495 if (((response >> 9) & 0xf) == state)
@@ -517,14 +517,14 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
517 int ret; 517 int ret;
518 unsigned char *buf_end, *buf = inbuf; 518 unsigned char *buf_end, *buf = inbuf;
519 int remaining = incount; 519 int remaining = incount;
520 const unsigned long *fifo_base = MMC_FIFO(drive); 520 const unsigned long *fifo_base = MCI_FIFO(drive);
521 521
522 /* skip SanDisk OF */ 522 /* skip SanDisk OF */
523 if (drive == NAND_AS3525) 523 if (drive == NAND_AS3525)
524#if defined(SANSA_E200V2) || defined(SANSA_FUZE) 524#if defined(SANSA_E200V2) || defined(SANSA_FUZE)
525 start += 61440; 525 start += 61440;
526#else 526#else
527 start += 20480; 527 start += 20480;
528#endif 528#endif
529 /* TODO: Add DMA support. */ 529 /* TODO: Add DMA support. */
530 530
@@ -542,6 +542,7 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
542 if (card_info[drive].initialized < 0) 542 if (card_info[drive].initialized < 0)
543 { 543 {
544 ret = card_info[drive].initialized; 544 ret = card_info[drive].initialized;
545 panicf("card not initalised");
545 goto sd_read_error; 546 goto sd_read_error;
546 } 547 }
547 548
@@ -549,7 +550,13 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
549 550
550 ret = sd_wait_for_state(drive, SD_TRAN); 551 ret = sd_wait_for_state(drive, SD_TRAN);
551 if (ret < 0) 552 if (ret < 0)
553 {
554 panicf("wait for state failed");
552 goto sd_read_error; 555 goto sd_read_error;
556 }
557
558 disable_irq(); /* FIXME: data transfer is too slow and error prone when
559 * interrupts are enabled */
553 560
554 while(remaining) 561 while(remaining)
555 { 562 {
@@ -558,20 +565,22 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
558 int transfer = (remaining >= 128) ? 127 : remaining; /* sectors */ 565 int transfer = (remaining >= 128) ? 127 : remaining; /* sectors */
559 566
560 if(card_info[drive].ocr & (1<<30) ) /* SDHC */ 567 if(card_info[drive].ocr & (1<<30) ) /* SDHC */
561 ret = send_cmd(drive, SD_READ_MULTIPLE_BLOCK, start, MMC_ARG, NULL); 568 ret = send_cmd(drive, SD_READ_MULTIPLE_BLOCK, start, MCI_ARG, NULL);
562 else 569 else
563 ret = send_cmd(drive, SD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, 570 ret = send_cmd(drive, SD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE,
564 MMC_ARG, NULL); 571 MCI_ARG, NULL);
565 572
566 if (ret < 0) 573 if (ret < 0)
574 {
575 panicf("read multiple blocks failed");
567 goto sd_read_error; 576 goto sd_read_error;
568 577 }
569 /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ 578 /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */
570 579
571 580
572 MMC_DATA_TIMER(drive) = 0x1000000; /* FIXME: arbitrary */ 581 MCI_DATA_TIMER(drive) = 0x1000000; /* FIXME: arbitrary */
573 MMC_DATA_LENGTH(drive) = transfer * card_info[drive].block_size; 582 MCI_DATA_LENGTH(drive) = transfer * card_info[drive].block_size;
574 MMC_DATA_CTRL(drive) = (1<<0) /* enable */ | 583 MCI_DATA_CTRL(drive) = (1<<0) /* enable */ |
575 (1<<1) /* from card to controller */ | 584 (1<<1) /* from card to controller */ |
576 (9<<4) /* 2^9 = 512 */ ; 585 (9<<4) /* 2^9 = 512 */ ;
577 586
@@ -580,43 +589,68 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
580 while(buf < buf_end) 589 while(buf < buf_end)
581 { 590 {
582 /* Wait for the FIFO to be half full */ 591 /* Wait for the FIFO to be half full */
583 if (!sd_poll_status(drive, ((1<<15)), 100)) 592 const int trigger = MCI_RX_FIFO_HALF_FULL|MCI_RX_FIFO_FULL;
584 { 593 int controller_status = sd_poll_status(drive, trigger, 100);
585 ret = -42; 594
586 goto sd_read_error; 595 controller_status &= ~(MCI_RX_ACTIVE|MCI_RX_DATA_AVAIL|
596 MCI_DATA_BLOCK_END|MCI_DATA_END);
597
598 if(!controller_status || (controller_status & ~trigger))
599 panicf("incorrect status 0x%x", controller_status & ~trigger);
600
601 if(((intptr_t)buf & 3) == 0)
602 { /* aligned destination buffer */
603 asm volatile(
604 "ldmia %2, {r0-r7} \n" /* load 8 * 4 bytes */
605 "stmia %1!, {r0-r7} \n" /* store 8 * 4 bytes */
606 :"=r"(buf) /* output */
607 :"r"(buf), "r"(fifo_base) /* input */
608 :"r0","r1","r2","r3","r4","r5","r6","r7" /* clobbers */
609 );
610 }
611 else
612 { /* non aligned destination buffer */
613 int tmp[8];
614 asm volatile(
615 "ldmia %1, {r0-r7} \n" /* load 8 * 4 bytes */
616 "stmia %0, {r0-r7} \n" /* store 8 * 4 bytes */
617 :/* no output */
618 :"r"(tmp), "r"(fifo_base) /* input */
619 :"r0","r1","r2","r3","r4","r5","r6","r7" /* clobbers */
620 );
621 memcpy(buf, tmp, 32);
622 buf = &buf[32];
587 } 623 }
588
589 asm volatile(
590 "ldmia %2, {r0-r7} \n" /* load 8 * 4 bytes */
591 "stmia %1!, {r0-r7} \n" /* store 8 * 4 bytes */
592 :"=r"(buf) /* output */
593 :"r"(buf), "r"(fifo_base) /* input */
594 :"r0","r1","r2","r3","r4","r5","r6","r7","r8" /* clobbers */
595 );
596 } 624 }
597 625
598 remaining -= transfer; 626 remaining -= transfer;
599 start += transfer; 627 start += transfer;
600 last_disk_activity = current_tick; 628 last_disk_activity = current_tick;
601 629
602 if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MMC_NO_FLAGS, NULL)) 630 if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_NO_FLAGS, NULL))
603 { 631 {
604 ret = -666; 632 ret = -666;
633 panicf("STOP TRANSMISSION failed");
605 goto sd_read_error; 634 goto sd_read_error;
606 } 635 }
607 636
608 ret = sd_wait_for_state(drive, SD_TRAN); 637 ret = sd_wait_for_state(drive, SD_TRAN);
609 if (ret < 0) 638 if (ret < 0)
639 {
640 panicf(" wait for state TRAN failed");
610 goto sd_read_error; 641 goto sd_read_error;
611 642 }
612 } 643 }
613 while (1) 644 while (1)
614 { 645 {
615 mutex_unlock(&sd_mtx); 646 mutex_unlock(&sd_mtx);
616 647
648 enable_irq();
649
617 return ret; 650 return ret;
618 651
619sd_read_error: 652sd_read_error:
653 panicf("read error : %d",ret);
620 card_info[drive].initialized = 0; 654 card_info[drive].initialized = 0;
621 } 655 }
622} 656}