summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/ata_sd_as3525.c
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2008-11-16 22:26:50 +0000
committerRafaël Carré <rafael.carre@gmail.com>2008-11-16 22:26:50 +0000
commitd3e783b268afd3ef9c96eaefaa0b3af5158b48a0 (patch)
tree7112007c866b5d6e962f86f7362e2e5c59b6d423 /firmware/target/arm/as3525/ata_sd_as3525.c
parent1b14167861bb5bf4c692f8fc661b33e26a706183 (diff)
downloadrockbox-d3e783b268afd3ef9c96eaefaa0b3af5158b48a0.tar.gz
rockbox-d3e783b268afd3ef9c96eaefaa0b3af5158b48a0.zip
Fix the Sansa AMS SD driver
- Make write_sectors() function fail. - Disable interrupts while transferring data and do not yield(), so we are sure the FIFO is not overflowed Note this solution is only temporary since it's not friendly to other threads and confuse kernel tick precision This will be reverted when we will be using DMA to access the SD card, but for now it permits further development - PL180: Rename the MMC_* registers into MCI_*, to not make people believe it is a MMC only controller - Supports non aligned destination buffers when reading - Correct the timeout units which were lamely copied from ata-sd-pp.c and were in milliseconds (note that the timeouts are disabled now) - Higher a bit the stack size - Use the full initialization procedure in the bootloader and the loaded firmware - Use the CCU_IO register only when a SD slot is present - Put some panicf() around to catch problems git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19122 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/ata_sd_as3525.c')
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c256
1 files changed, 145 insertions, 111 deletions
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}