summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/mmc.h50
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c368
2 files changed, 228 insertions, 190 deletions
diff --git a/firmware/export/mmc.h b/firmware/export/mmc.h
index 4c7e9c0926..8d20f81236 100644
--- a/firmware/export/mmc.h
+++ b/firmware/export/mmc.h
@@ -55,5 +55,55 @@ long mmc_last_disk_activity(void);
55int mmc_num_drives(int first_drive); 55int mmc_num_drives(int first_drive);
56#endif 56#endif
57 57
58/* MMC States */
59#define MMC_IDLE 0
60#define MMC_READY 1
61#define MMC_IDENT 2
62#define MMC_STBY 3
63#define MMC_TRAN 4
64#define MMC_DATA 5
65#define MMC_RCV 6
66#define MMC_PRG 7
67#define MMC_DIS 8
68#define MMC_BTST 9
69
70/* MMC Commands */
71#define MMC_GO_IDLE_STATE 0
72#define MMC_SEND_OP_COND 1
73#define MMC_ALL_SEND_CID 2
74#define MMC_SET_RELATIVE_ADDR 3
75#define MMC_SET_DSR 4
76#define MMC_SWITCH 6
77#define MMC_SELECT_CARD 7 /* with card's rca */
78#define MMC_DESELECT_CARD 7 /* with rca = 0 */
79#define MMC_SEND_EXT_CSD 8
80#define MMC_SEND_CSD 9
81#define MMC_SEND_CID 10
82#define MMC_READ_DAT_UNTIL_STOP 11
83#define MMC_STOP_TRANSMISSION 12
84#define MMC_SEND_STATUS 13
85#define MMC_BUSTEST_R 14
86#define MMC_GO_INACTIVE_STATE 15
87#define MMC_SET_BLOCKLEN 16
88#define MMC_READ_SINGLE_BLOCK 17
89#define MMC_READ_MULTIPLE_BLOCK 18
90#define MMC_BUSTEST_W 19
91#define MMC_WRITE_DAT_UNTIL_STOP 20
92#define MMC_SET_BLOCK_COUNT 23
93#define MMC_WRITE_BLOCK 24
94#define MMC_WRITE_MULTIPLE_BLOCK 25
95#define MMC_PROGRAM_CID 26
96#define MMC_PROGRAM_CSD 27
97#define MMC_SET_WRITE_PROT 28
98#define MMC_CLR_WRITE_PROT 29
99#define MMC_SEND_WRITE_PROT 30
100#define MMC_ERASE_GROUP_START 35
101#define MMC_ERASE_GROUP_END 36
102#define MMC_ERASE 38
103#define MMC_FAST_IO 39
104#define MMC_GO_IRQ_STATE 40
105#define MMC_LOCK_UNLOCK 42
106#define MMC_APP_CMD 55
107#define MMC_GEN_CMD 56
58 108
59#endif 109#endif
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index c52734f471..5309f844f2 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -21,6 +21,7 @@
21#include "config.h" 21#include "config.h"
22#include "system.h" 22#include "system.h"
23#include "sd.h" 23#include "sd.h"
24#include "mmc.h"
24#include "sdmmc.h" 25#include "sdmmc.h"
25#include "ssp-imx233.h" 26#include "ssp-imx233.h"
26#include "pinctrl-imx233.h" 27#include "pinctrl-imx233.h"
@@ -32,6 +33,24 @@
32#include "debug.h" 33#include "debug.h"
33#include "string.h" 34#include "string.h"
34 35
36/** NOTE For convenience, this drivers relies on the many similar commands
37 * between SD and MMC. The following assumptions are made:
38 * - SD_SEND_STATUS = MMC_SEND_STATUS
39 * - SD_SELECT_CARD = MMC_SELECT_CARD
40 * - SD_TRAN = MMC_TRAN
41 * - MMC_WRITE_MULTIPLE_BLOCK = SD_WRITE_MULTIPLE_BLOCK
42 * - MMC_READ_MULTIPLE_BLOCK = SD_READ_MULTIPLE_BLOCK
43 * - SD_STOP_TRANSMISSION = MMC_STOP_TRANSMISSION
44 * - SD_DESELECT_CARD = MMC_DESELECT_CARD
45 */
46#if SD_SEND_STATUS != MMC_SEND_STATUS || SD_SELECT_CARD != MMC_SELECT_CARD || \
47 SD_TRAN != MMC_TRAN || MMC_WRITE_MULTIPLE_BLOCK != SD_WRITE_MULTIPLE_BLOCK || \
48 MMC_READ_MULTIPLE_BLOCK != SD_READ_MULTIPLE_BLOCK || \
49 SD_STOP_TRANSMISSION != MMC_STOP_TRANSMISSION || \
50 SD_DESELECT_CARD != MMC_DESELECT_CARD
51#error SD/MMC mismatch
52#endif
53
35struct sdmmc_config_t 54struct sdmmc_config_t
36{ 55{
37 const char *name; /* name(for debug) */ 56 const char *name; /* name(for debug) */
@@ -115,11 +134,18 @@ struct sdmmc_config_t sdmmc_config[] =
115#define SDMMC_SSP(drive) SDMMC_CONF(drive).ssp 134#define SDMMC_SSP(drive) SDMMC_CONF(drive).ssp
116#define SDMMC_MODE(drive) SDMMC_CONF(drive).mode 135#define SDMMC_MODE(drive) SDMMC_CONF(drive).mode
117 136
137/** WARNING
138 * to be consistent with all our SD drivers, the .rca field of sdmmc_card_info
139 * in reality holds (rca << 16) because all command arguments actually require
140 * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */
141
118/* common */ 142/* common */
119static unsigned window_start[SDMMC_NUM_DRIVES]; 143static unsigned window_start[SDMMC_NUM_DRIVES];
120static unsigned window_end[SDMMC_NUM_DRIVES]; 144static unsigned window_end[SDMMC_NUM_DRIVES];
121static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR; 145static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR;
122static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; 146static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
147static struct mutex mutex[SDMMC_NUM_DRIVES];
148static int disk_last_activity[SDMMC_NUM_DRIVES];
123 149
124#define SDMMC_INFO(drive) sdmmc_card_info[drive] 150#define SDMMC_INFO(drive) sdmmc_card_info[drive]
125#define SDMMC_RCA(drive) SDMMC_INFO(drive).rca 151#define SDMMC_RCA(drive) SDMMC_INFO(drive).rca
@@ -127,19 +153,16 @@ static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
127/* sd only */ 153/* sd only */
128#if CONFIG_STORAGE & STORAGE_SD 154#if CONFIG_STORAGE & STORAGE_SD
129static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 155static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
130static struct mutex sd_mutex;
131static const char sd_thread_name[] = "sd"; 156static const char sd_thread_name[] = "sd";
132static struct event_queue sd_queue; 157static struct event_queue sd_queue;
133static int sd_first_drive; 158static int sd_first_drive;
134static unsigned _sd_num_drives; 159static unsigned _sd_num_drives;
135static int _sd_last_disk_activity;
136static int sd_map[SDMMC_NUM_DRIVES]; /* sd->sdmmc map */ 160static int sd_map[SDMMC_NUM_DRIVES]; /* sd->sdmmc map */
137#endif 161#endif
138/* mmc only */ 162/* mmc only */
139#if CONFIG_STORAGE & STORAGE_MMC 163#if CONFIG_STORAGE & STORAGE_MMC
140static int mmc_first_drive; 164static int mmc_first_drive;
141static unsigned _mmc_num_drives; 165static unsigned _mmc_num_drives;
142static int _mmc_last_disk_activity;
143static int mmc_map[SDMMC_NUM_DRIVES]; /* mmc->sdmmc map */ 166static int mmc_map[SDMMC_NUM_DRIVES]; /* mmc->sdmmc map */
144#endif 167#endif
145 168
@@ -193,13 +216,13 @@ static void sdmmc_power(int drive, bool on)
193#define MCI_NO_RESP 0 216#define MCI_NO_RESP 0
194#define MCI_RESP (1<<0) 217#define MCI_RESP (1<<0)
195#define MCI_LONG_RESP (1<<1) 218#define MCI_LONG_RESP (1<<1)
196#define MCI_ACMD (1<<2) 219#define MCI_ACMD (1<<2) /* sd only */
197#define MCI_NOCRC (1<<3) 220#define MCI_NOCRC (1<<3)
198#define MCI_BUSY (1<<4) 221#define MCI_BUSY (1<<4)
199 222
200static bool send_sd_cmd(int drive, uint8_t cmd, uint32_t arg, uint32_t flags, uint32_t *resp) 223static bool send_cmd(int drive, uint8_t cmd, uint32_t arg, uint32_t flags, uint32_t *resp)
201{ 224{
202 if((flags & MCI_ACMD) && !send_sd_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, resp)) 225 if((flags & MCI_ACMD) && !send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, resp))
203 return false; 226 return false;
204 227
205 enum imx233_ssp_resp_t resp_type = (flags & MCI_LONG_RESP) ? SSP_LONG_RESP : 228 enum imx233_ssp_resp_t resp_type = (flags & MCI_LONG_RESP) ? SSP_LONG_RESP :
@@ -219,7 +242,7 @@ static bool send_sd_cmd(int drive, uint8_t cmd, uint32_t arg, uint32_t flags, ui
219 return ret == SSP_SUCCESS; 242 return ret == SSP_SUCCESS;
220} 243}
221 244
222static int wait_for_sd_tran_state(int drive) 245static int wait_for_state(int drive, unsigned state)
223{ 246{
224 unsigned long response; 247 unsigned long response;
225 unsigned int timeout = current_tick + 5*HZ; 248 unsigned int timeout = current_tick + 5*HZ;
@@ -227,26 +250,27 @@ static int wait_for_sd_tran_state(int drive)
227 250
228 while (1) 251 while (1)
229 { 252 {
230 while(!send_sd_cmd(drive, SD_SEND_STATUS, SDMMC_RCA(drive), MCI_RESP, &response) && cmd_retry > 0) 253 /* NOTE: rely on SD_SEND_STATUS=MMC_SEND_STATUS */
254 while(!send_cmd(drive, SD_SEND_STATUS, SDMMC_RCA(drive), MCI_RESP, &response) && cmd_retry > 0)
231 cmd_retry--; 255 cmd_retry--;
232 256
233 if(cmd_retry <= 0) 257 if(cmd_retry <= 0)
234 return -1; 258 return -1;
235 259
236 if(((response >> 9) & 0xf) == SD_TRAN) 260 if(((response >> 9) & 0xf) == state)
237 return 0; 261 return 0;
238 262
239 if(TIME_AFTER(current_tick, timeout)) 263 if(TIME_AFTER(current_tick, timeout))
240 return -10 * ((response >> 9) & 0xf); 264 return -10 * ((response >> 9) & 0xf);
241 265
242 _sd_last_disk_activity = current_tick; 266 disk_last_activity[drive] = current_tick;
243 } 267 }
244 268
245 return 0; 269 return 0;
246} 270}
247 271
248#if CONFIG_STORAGE & STORAGE_SD 272#if CONFIG_STORAGE & STORAGE_SD
249static int sdmmc_init_sd_card(int drive) 273static int init_sd_card(int drive)
250{ 274{
251 int ssp = SDMMC_SSP(drive); 275 int ssp = SDMMC_SSP(drive);
252 sdmmc_power(drive, false); 276 sdmmc_power(drive, false);
@@ -267,11 +291,11 @@ static int sdmmc_init_sd_card(int drive)
267 uint32_t resp; 291 uint32_t resp;
268 long init_timeout; 292 long init_timeout;
269 /* go to idle state */ 293 /* go to idle state */
270 if(!send_sd_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL)) 294 if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL))
271 return -1; 295 return -1;
272 /* CMD8 Check for v2 sd card. Must be sent before using ACMD41 296 /* CMD8 Check for v2 sd card. Must be sent before using ACMD41
273 Non v2 cards will not respond to this command */ 297 Non v2 cards will not respond to this command */
274 if(send_sd_cmd(drive, SD_SEND_IF_COND, 0x1AA, MCI_RESP, &resp)) 298 if(send_cmd(drive, SD_SEND_IF_COND, 0x1AA, MCI_RESP, &resp))
275 if((resp & 0xFFF) == 0x1AA) 299 if((resp & 0xFFF) == 0x1AA)
276 sd_v2 = true; 300 sd_v2 = true;
277 /* timeout for initialization is 1sec, from SD Specification 2.00 */ 301 /* timeout for initialization is 1sec, from SD Specification 2.00 */
@@ -283,42 +307,42 @@ static int sdmmc_init_sd_card(int drive)
283 return -2; 307 return -2;
284 308
285 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ 309 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
286 if(!send_sd_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), 310 if(!send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)),
287 MCI_ACMD|MCI_NOCRC|MCI_RESP, &SDMMC_INFO(drive).ocr)) 311 MCI_ACMD|MCI_NOCRC|MCI_RESP, &SDMMC_INFO(drive).ocr))
288 return -100; 312 return -100;
289 } while(!(SDMMC_INFO(drive).ocr & (1<<31))); 313 } while(!(SDMMC_INFO(drive).ocr & (1<<31)));
290 314
291 /* CMD2 send CID */ 315 /* CMD2 send CID */
292 if(!send_sd_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, SDMMC_INFO(drive).cid)) 316 if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, SDMMC_INFO(drive).cid))
293 return -3; 317 return -3;
294 318
295 /* CMD3 send RCA */ 319 /* CMD3 send RCA */
296 if(!send_sd_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &SDMMC_INFO(drive).rca)) 320 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &SDMMC_INFO(drive).rca))
297 return -4; 321 return -4;
298 322
299 /* Try to switch V2 cards to HS timings, non HS seem to ignore this */ 323 /* Try to switch V2 cards to HS timings, non HS seem to ignore this */
300 if(sd_v2) 324 if(sd_v2)
301 { 325 {
302 /* CMD7 w/rca: Select card to put it in TRAN state */ 326 /* CMD7 w/rca: Select card to put it in TRAN state */
303 if(!send_sd_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, NULL)) 327 if(!send_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, NULL))
304 return -5; 328 return -5;
305 329
306 if(wait_for_sd_tran_state(drive)) 330 if(wait_for_state(drive, SD_TRAN))
307 return -6; 331 return -6;
308 332
309 /* CMD6 */ 333 /* CMD6 */
310 if(!send_sd_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL)) 334 if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL))
311 return -7; 335 return -7;
312 sleep(HZ/10); 336 sleep(HZ/10);
313 337
314 /* go back to STBY state so we can read csd */ 338 /* go back to STBY state so we can read csd */
315 /* CMD7 w/rca=0: Deselect card to put it in STBY state */ 339 /* CMD7 w/rca=0: Deselect card to put it in STBY state */
316 if(!send_sd_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL)) 340 if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
317 return -8; 341 return -8;
318 } 342 }
319 343
320 /* CMD9 send CSD */ 344 /* CMD9 send CSD */
321 if(!send_sd_cmd(drive, SD_SEND_CSD, SDMMC_RCA(drive), MCI_RESP|MCI_LONG_RESP, 345 if(!send_cmd(drive, SD_SEND_CSD, SDMMC_RCA(drive), MCI_RESP|MCI_LONG_RESP,
322 SDMMC_INFO(drive).csd)) 346 SDMMC_INFO(drive).csd))
323 return -9; 347 return -9;
324 348
@@ -331,16 +355,16 @@ static int sdmmc_init_sd_card(int drive)
331 imx233_ssp_set_timings(ssp, 4, 0, 0xffff); 355 imx233_ssp_set_timings(ssp, 4, 0, 0xffff);
332 356
333 /* CMD7 w/rca: Select card to put it in TRAN state */ 357 /* CMD7 w/rca: Select card to put it in TRAN state */
334 if(!send_sd_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, &resp)) 358 if(!send_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, &resp))
335 return -12; 359 return -12;
336 if(wait_for_sd_tran_state(drive) < 0) 360 if(wait_for_state(drive, SD_TRAN))
337 return -13; 361 return -13;
338 362
339 /* ACMD6: set bus width to 4-bit */ 363 /* ACMD6: set bus width to 4-bit */
340 if(!send_sd_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_RESP|MCI_ACMD, &resp)) 364 if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_RESP|MCI_ACMD, &resp))
341 return -15; 365 return -15;
342 /* ACMD42: disconnect the pull-up resistor on CD/DAT3 */ 366 /* ACMD42: disconnect the pull-up resistor on CD/DAT3 */
343 if(!send_sd_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_RESP|MCI_ACMD, &resp)) 367 if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_RESP|MCI_ACMD, &resp))
344 return -17; 368 return -17;
345 369
346 /* Switch to 4-bit */ 370 /* Switch to 4-bit */
@@ -350,115 +374,15 @@ static int sdmmc_init_sd_card(int drive)
350 374
351 return 0; 375 return 0;
352} 376}
353
354static int transfer_sd_sectors(int drive, unsigned long start, int count, void *buf, bool read)
355{
356 int ret = 0;
357 uint32_t resp;
358
359 _sd_last_disk_activity = current_tick;
360
361 mutex_lock(&sd_mutex);
362
363 if(SDMMC_INFO(drive).initialized <= 0)
364 {
365 ret = sdmmc_init_sd_card(drive);
366 if(SDMMC_INFO(drive).initialized <= 0)
367 goto Lend;
368 }
369
370 /* check window */
371 start += window_start[drive];
372 if((start + count) > window_end[drive])
373 {
374 ret = -201;
375 goto Lend;
376 }
377
378 if(!send_sd_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_NO_RESP, NULL))
379 {
380 ret = -20;
381 goto Lend;
382 }
383 ret = wait_for_sd_tran_state(drive);
384 if(ret < 0)
385 goto Ldeselect;
386 while(count != 0)
387 {
388 /* FIXME implement this_count > 1 by using a sub-buffer of [sub] that is
389 * cache-aligned and then moving the data when possible. This way we could
390 * transfer much greater amount of data at once */
391 int this_count = 1;
392 /* Set bank_start to the correct unit (blocks or bytes) */
393 int bank_start = start;
394 if(!(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */
395 bank_start *= SD_BLOCK_SIZE;
396 if(!read)
397 memcpy(aligned_buffer[drive], buf, 512);
398 ret = imx233_ssp_sd_mmc_transfer(SDMMC_SSP(drive),
399 read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK,
400 bank_start, SSP_SHORT_RESP, aligned_buffer[drive], this_count, false, read, &resp);
401 if(ret != SSP_SUCCESS)
402 break;
403 if(!send_sd_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP|MCI_BUSY, &resp))
404 {
405 ret = -15;
406 break;
407 }
408 if(read)
409 memcpy(buf, aligned_buffer[drive], 512);
410 count -= this_count;
411 start += this_count;
412 buf += this_count * 512;
413 }
414
415 Ldeselect:
416 /* CMD7 w/rca =0 : deselects card & puts it in STBY state */
417 if(!send_sd_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
418 ret = -23;
419 Lend:
420 mutex_unlock(&sd_mutex);
421 return ret;
422}
423#endif 377#endif
424 378
425#if CONFIG_STORAGE & STORAGE_MMC 379#if CONFIG_STORAGE & STORAGE_MMC
426static int transfer_mmc_sectors(int drive, unsigned long start, int count, void *buf, bool read) 380static int init_mmc_drive(int drive)
427{
428 /* check window */
429 start += window_start[drive];
430 if((start + count) > window_end[drive])
431 return -201;
432 int ret = 0;
433 uint32_t resp;
434
435 _mmc_last_disk_activity = current_tick;
436
437 do
438 {
439 /* FIXME implement this_count > 1 by using a sub-buffer of [sub] that is
440 * cache-aligned and then moving the data when possible. This way we could
441 * transfer much greater amount of data at once */
442 int this_count = 1;
443 if(!read)
444 memcpy(aligned_buffer[drive], buf, 512);
445 ret = imx233_ssp_sd_mmc_transfer(SDMMC_SSP(drive), read ? 17 : 24, start,
446 SSP_SHORT_RESP, aligned_buffer[drive], this_count, false, read, &resp);
447 if(read)
448 memcpy(buf, aligned_buffer[drive], 512);
449 count -= this_count;
450 start += this_count;
451 buf += this_count * 512;
452 }while(count != 0 && ret == SSP_SUCCESS);
453
454 return ret;
455}
456
457static int sdmmc_init_mmc_drive(int drive)
458{ 381{
459 int ssp = SDMMC_SSP(drive); 382 int ssp = SDMMC_SSP(drive);
460 // we can choose the RCA of mmc cards: pick drive 383 /* we can choose the RCA of mmc cards: pick drive. Following our convention,
461 SDMMC_RCA(drive) = drive; 384 * .rca is actually RCA << 16 */
385 SDMMC_RCA(drive) = drive << 16;
462 386
463 sdmmc_power(drive, false); 387 sdmmc_power(drive, false);
464 sdmmc_power(drive, true); 388 sdmmc_power(drive, true);
@@ -472,52 +396,44 @@ static int sdmmc_init_mmc_drive(int drive)
472 imx233_ssp_set_bus_width(ssp, 1); 396 imx233_ssp_set_bus_width(ssp, 1);
473 imx233_ssp_set_block_size(ssp, 9); 397 imx233_ssp_set_block_size(ssp, 9);
474 /* go to idle state */ 398 /* go to idle state */
475 int ret = imx233_ssp_sd_mmc_transfer(ssp, 0, 0, SSP_NO_RESP, NULL, 0, false, false, NULL); 399 if(!send_cmd(drive, MMC_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL))
476 if(ret != 0)
477 return -1; 400 return -1;
478 /* send op cond until the card respond with busy bit set; it must complete within 1sec */ 401 /* send op cond until the card respond with busy bit set; it must complete within 1sec */
479 unsigned timeout = current_tick + HZ; 402 unsigned timeout = current_tick + HZ;
403 bool ret = false;
480 do 404 do
481 { 405 {
482 uint32_t ocr; 406 uint32_t ocr;
483 ret = imx233_ssp_sd_mmc_transfer(ssp, 1, 0x40ff8000, SSP_SHORT_RESP, NULL, 0, false, false, &ocr); 407 ret = send_cmd(drive, MMC_SEND_OP_COND, 0x40ff8000, MCI_RESP, &ocr);
484 if(ret == 0 && ocr & (1 << 31)) 408 if(ret && ocr & (1 << 31))
485 break; 409 break;
486 }while(!TIME_AFTER(current_tick, timeout)); 410 }while(!TIME_AFTER(current_tick, timeout));
487 411
488 if(ret != 0) 412 if(!ret)
489 return -2; 413 return -2;
490 /* get CID */ 414 /* get CID */
491 uint32_t cid[4]; 415 uint32_t cid[4];
492 ret = imx233_ssp_sd_mmc_transfer(ssp, 2, 0, SSP_LONG_RESP, NULL, 0, false, false, cid); 416 if(!send_cmd(drive, MMC_ALL_SEND_CID, 0, MCI_LONG_RESP, cid))
493 if(ret != 0)
494 return -3; 417 return -3;
495 /* Set RCA */ 418 /* Set RCA */
496 uint32_t status; 419 uint32_t status;
497 ret = imx233_ssp_sd_mmc_transfer(ssp, 3, SDMMC_RCA(drive) << 16, SSP_SHORT_RESP, NULL, 0, false, false, &status); 420 if(!send_cmd(drive, MMC_SET_RELATIVE_ADDR, SDMMC_RCA(drive), MCI_RESP, &status))
498 if(ret != 0)
499 return -4; 421 return -4;
500 /* Select card */ 422 /* Select card */
501 ret = imx233_ssp_sd_mmc_transfer(ssp, 7, SDMMC_RCA(drive) << 16, SSP_SHORT_RESP, NULL, 0, false, false, &status); 423 if(!send_cmd(drive, MMC_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, &status))
502 if(ret != 0)
503 return -5; 424 return -5;
504 /* Check TRAN state */ 425 /* Check TRAN state */
505 ret = imx233_ssp_sd_mmc_transfer(ssp, 13, SDMMC_RCA(drive) << 16, SSP_SHORT_RESP, NULL, 0, false, false, &status); 426 if(wait_for_state(drive, MMC_TRAN))
506 if(ret != 0)
507 return -6; 427 return -6;
508 if(((status >> 9) & 0xf) != 4)
509 return -7;
510 /* Switch to 8-bit bus */ 428 /* Switch to 8-bit bus */
511 ret = imx233_ssp_sd_mmc_transfer(ssp, 6, 0x3b70200, SSP_SHORT_RESP, NULL, 0, true, false, &status); 429 if(!send_cmd(drive, MMC_SWITCH, 0x3b70200, MCI_RESP|MCI_BUSY, &status))
512 if(ret != 0)
513 return -8; 430 return -8;
514 /* switch error ? */ 431 /* switch error ? */
515 if(status & 0x80) 432 if(status & 0x80)
516 return -9; 433 return -9;
517 imx233_ssp_set_bus_width(ssp, 8); 434 imx233_ssp_set_bus_width(ssp, 8);
518 /* Switch to high speed mode */ 435 /* Switch to high speed mode */
519 ret = imx233_ssp_sd_mmc_transfer(ssp, 6, 0x3b90100, SSP_SHORT_RESP, NULL, 0, true, false, &status); 436 if(!send_cmd(drive, MMC_SWITCH, 0x3b90100, MCI_RESP|MCI_BUSY, &status))
520 if(ret != 0)
521 return -10; 437 return -10;
522 /* switch error ?*/ 438 /* switch error ?*/
523 if(status & 0x80) 439 if(status & 0x80)
@@ -529,76 +445,139 @@ static int sdmmc_init_mmc_drive(int drive)
529 /* read extended CSD */ 445 /* read extended CSD */
530 { 446 {
531 uint8_t ext_csd[512]; 447 uint8_t ext_csd[512];
532 ret = imx233_ssp_sd_mmc_transfer(ssp, 8, 0, SSP_SHORT_RESP, aligned_buffer[drive], 1, true, true, &status); 448 if(imx233_ssp_sd_mmc_transfer(ssp, 8, 0, SSP_SHORT_RESP, aligned_buffer[drive], 1, true, true, &status))
533 if(ret != 0)
534 return -12; 449 return -12;
535 memcpy(ext_csd, aligned_buffer[drive], 512); 450 memcpy(ext_csd, aligned_buffer[drive], 512);
536 uint32_t *sec_count = (void *)&ext_csd[212]; 451 uint32_t *sec_count = (void *)&ext_csd[212];
537 window_start[drive] = 0; 452 window_start[drive] = 0;
538 window_end[drive] = *sec_count; 453 window_end[drive] = *sec_count;
539 } 454 }
455 /* deselect card */
456 if(!send_cmd(drive, MMC_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
457 return -13;
540 458
541 return 0; 459 return 0;
542} 460}
543#endif 461#endif
544 462
545static int sdmmc_read_sectors(int drive, unsigned long start, int count, void* buf) 463static int transfer_sectors(int drive, unsigned long start, int count, void *buf, bool read)
546{ 464{
547 switch(SDMMC_MODE(drive)) 465 int ret = 0;
548 { 466 uint32_t resp;
467
468 /* update disk activity */
469 disk_last_activity[drive] = current_tick;
470
471 /* lock per-drive mutex */
472 mutex_lock(&mutex[drive]);
473
474 /* for SD cards, init if necessary */
549#if CONFIG_STORAGE & STORAGE_SD 475#if CONFIG_STORAGE & STORAGE_SD
550 case SD_MODE: return transfer_sd_sectors(drive, start, count, buf, true); 476 if(SDMMC_MODE(drive) == SD_MODE && SDMMC_INFO(drive).initialized <= 0)
551#endif 477 {
552#if CONFIG_STORAGE & STORAGE_MMC 478 ret = init_sd_card(drive);
553 case MMC_MODE: return transfer_mmc_sectors(drive, start, count, buf, true); 479 if(SDMMC_INFO(drive).initialized <= 0)
480 goto Lend;
481 }
554#endif 482#endif
555 default: return -1; 483
484 /* check window */
485 start += window_start[drive];
486 if((start + count) > window_end[drive])
487 {
488 ret = -201;
489 goto Lend;
556 } 490 }
557}
558 491
559static int sdmmc_write_sectors(int drive, unsigned long start, int count, const void* buf) 492 /* select card.
560{ 493 * NOTE: rely on SD_SELECT_CARD=MMC_SELECT_CARD */
561 switch(SDMMC_MODE(drive)) 494 if(!send_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_NO_RESP, NULL))
562 { 495 {
563#if CONFIG_STORAGE & STORAGE_SD 496 ret = -20;
564 case SD_MODE: return transfer_sd_sectors(drive, start, count, (void *)buf, false); 497 goto Lend;
565#endif
566#if CONFIG_STORAGE & STORAGE_MMC
567 case MMC_MODE: return transfer_mmc_sectors(drive, start, count, (void *)buf, false);
568#endif
569 default: return -1;
570 } 498 }
499 /* wait for TRAN state */
500 /* NOTE: rely on SD_TRAN=MMC_TRAN */
501 ret = wait_for_state(drive, SD_TRAN);
502 if(ret < 0)
503 goto Ldeselect;
504 while(count != 0)
505 {
506 /* FIXME implement this_count > 1 by using a sub-buffer of [sub] that is
507 * cache-aligned and then moving the data when possible. This way we could
508 * transfer much greater amount of data at once */
509 int this_count = 1;
510 /* Set bank_start to the correct unit (blocks or bytes).
511 * MMC drives use block addressing, SD cards bytes or blocks */
512 int bank_start = start;
513 if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */
514 bank_start *= SD_BLOCK_SIZE;
515 /* on write transfers, copy data to the aligned buffer */
516 if(!read)
517 memcpy(aligned_buffer[drive], buf, 512);
518 /* issue read/write
519 * NOTE: rely on SD_{READ,WRITE}_MULTIPLE_BLOCK=MMC_{READ,WRITE}_MULTIPLE_BLOCK */
520 ret = imx233_ssp_sd_mmc_transfer(SDMMC_SSP(drive),
521 read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK,
522 bank_start, SSP_SHORT_RESP, aligned_buffer[drive], this_count, false, read, &resp);
523 if(ret != SSP_SUCCESS)
524 break;
525 /* stop transmission
526 * NOTE: rely on SD_STOP_TRANSMISSION=MMC_STOP_TRANSMISSION */
527 if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP|MCI_BUSY, &resp))
528 {
529 ret = -15;
530 break;
531 }
532 /* on read transfers, copy the data back to the user buffer */
533 if(read)
534 memcpy(buf, aligned_buffer[drive], 512);
535 count -= this_count;
536 start += this_count;
537 buf += this_count * 512;
538 }
539 /* deselect card */
540 Ldeselect:
541 /* CMD7 w/rca =0 : deselects card & puts it in STBY state
542 * NOTE: rely on SD_DESELECT_CARD=MMC_DESELECT_CARD */
543 if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
544 ret = -23;
545 Lend:
546 /* release per-drive mutex */
547 mutex_unlock(&mutex[drive]);
548 return ret;
571} 549}
572 550
573static int sdmmc_init_drive(int drive) 551static int init_drive(int drive)
574{ 552{
575 int ret; 553 int ret;
576 switch(SDMMC_MODE(drive)) 554 switch(SDMMC_MODE(drive))
577 { 555 {
578#if CONFIG_STORAGE & STORAGE_SD 556#if CONFIG_STORAGE & STORAGE_SD
579 case SD_MODE: ret = sdmmc_init_sd_card(drive); break; 557 case SD_MODE: ret = init_sd_card(drive); break;
580#endif 558#endif
581#if CONFIG_STORAGE & STORAGE_MMC 559#if CONFIG_STORAGE & STORAGE_MMC
582 case MMC_MODE: ret = sdmmc_init_mmc_drive(drive); break; 560 case MMC_MODE: ret = init_mmc_drive(drive); break;
583#endif 561#endif
584 default: ret = 0; 562 default: ret = 0;
585 } 563 }
586 if(ret < 0) 564 if(ret < 0)
565 panicf("die %d", ret);
566 if(ret < 0)
587 return ret; 567 return ret;
588 568
589 /* compute window */ 569 /* compute window */
590 if((SDMMC_FLAGS(drive) & WINDOW) && imx233_partitions_is_window_enabled()) 570 if((SDMMC_FLAGS(drive) & WINDOW) && imx233_partitions_is_window_enabled())
591 { 571 {
592 uint8_t mbr[512]; 572 uint8_t mbr[512];
593 int ret = sdmmc_read_sectors(IF_MD2(drive,) 0, 1, mbr); 573 int ret = transfer_sectors(drive, 0, 1, mbr, true);
594 if(ret) 574 if(ret)
595 panicf("Cannot read MBR: %d", ret); 575 panicf("Cannot read MBR: %d", ret);
596 ret = imx233_partitions_compute_window(mbr, &window_start[drive], 576 ret = imx233_partitions_compute_window(mbr, &window_start[drive],
597 &window_end[drive]); 577 &window_end[drive]);
598 if(ret) 578 if(ret)
599 panicf("cannot compute partitions window: %d", ret); 579 panicf("cannot compute partitions window: %d", ret);
600 if(SDMMC_MODE(drive) == SD_MODE) 580 SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive];
601 SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive];
602 } 581 }
603 582
604 return 0; 583 return 0;
@@ -624,9 +603,6 @@ static void sd_thread(void)
624 * would cause a reverse-order attempt with 603 * would cause a reverse-order attempt with
625 * another thread */ 604 * another thread */
626 fat_lock(); 605 fat_lock();
627 /* lock-out card activity - direct calls
628 * into driver that bypass the fat cache */
629 mutex_lock(&sd_mutex);
630 606
631 /* We now have exclusive control of fat cache and sd. 607 /* We now have exclusive control of fat cache and sd.
632 * Release "by force", ensure file 608 * Release "by force", ensure file
@@ -634,9 +610,13 @@ static void sd_thread(void)
634 * ones are invalid if mounting. */ 610 * ones are invalid if mounting. */
635 for(unsigned sd_drive = 0; sd_drive < _sd_num_drives; sd_drive++) 611 for(unsigned sd_drive = 0; sd_drive < _sd_num_drives; sd_drive++)
636 { 612 {
613 int drive = sd_map[sd_drive];
637 /* Skip non-removable drivers */ 614 /* Skip non-removable drivers */
638 if(!sd_removable(sd_drive)) 615 if(!sd_removable(sd_drive))
639 continue; 616 continue;
617 /* lock-out card activity - direct calls
618 * into driver that bypass the fat cache */
619 mutex_lock(&mutex[drive]);
640 disk_unmount(sd_first_drive + sd_drive); 620 disk_unmount(sd_first_drive + sd_drive);
641 /* Force card init for new card, re-init for re-inserted one or 621 /* Force card init for new card, re-init for re-inserted one or
642 * clear if the last attempt to init failed with an error. */ 622 * clear if the last attempt to init failed with an error. */
@@ -644,7 +624,7 @@ static void sd_thread(void)
644 624
645 if(ev.id == SYS_HOTSWAP_INSERTED) 625 if(ev.id == SYS_HOTSWAP_INSERTED)
646 { 626 {
647 microsd_init = sdmmc_init_drive(sd_map[sd_drive]); 627 microsd_init = init_drive(drive);
648 if(microsd_init < 0) /* initialisation failed */ 628 if(microsd_init < 0) /* initialisation failed */
649 panicf("%s init failed : %d", SDMMC_CONF(sd_map[sd_drive]).name, microsd_init); 629 panicf("%s init failed : %d", SDMMC_CONF(sd_map[sd_drive]).name, microsd_init);
650 630
@@ -656,14 +636,15 @@ static void sd_thread(void)
656 */ 636 */
657 if(microsd_init) 637 if(microsd_init)
658 queue_broadcast(SYS_FS_CHANGED, 0); 638 queue_broadcast(SYS_FS_CHANGED, 0);
639 /* unlock card */
640 mutex_unlock(&mutex[drive]);
659 } 641 }
660 /* Access is now safe */ 642 /* Access is now safe */
661 mutex_unlock(&sd_mutex);
662 fat_unlock(); 643 fat_unlock();
663 break; 644 break;
664 } 645 }
665 case SYS_TIMEOUT: 646 case SYS_TIMEOUT:
666 if(!TIME_BEFORE(current_tick, _sd_last_disk_activity + 3 * HZ)) 647 if(!TIME_BEFORE(current_tick, sd_last_disk_activity() + 3 * HZ))
667 sd_enable(false); 648 sd_enable(false);
668 break; 649 break;
669 case SYS_USB_CONNECTED: 650 case SYS_USB_CONNECTED:
@@ -675,15 +656,16 @@ static void sd_thread(void)
675 } 656 }
676} 657}
677 658
678int sdmmc_init(void) 659static int sdmmc_init(void)
679{ 660{
680 static int is_initialized = false; 661 static int is_initialized = false;
681 if(is_initialized) 662 if(is_initialized)
682 return 0; 663 return 0;
683 is_initialized = true; 664 is_initialized = true;
665 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
666 mutex_init(&mutex[drive]);
684 667
685#if CONFIG_STORAGE & STORAGE_SD 668#if CONFIG_STORAGE & STORAGE_SD
686 mutex_init(&sd_mutex);
687 queue_init(&sd_queue, true); 669 queue_init(&sd_queue, true);
688 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, 670 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
689 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); 671 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
@@ -748,7 +730,10 @@ bool sd_removable(IF_MV_NONVOID(int sd_drive))
748 730
749long sd_last_disk_activity(void) 731long sd_last_disk_activity(void)
750{ 732{
751 return _sd_last_disk_activity; 733 long last = 0;
734 for(unsigned i = 0; i < _sd_num_drives; i++)
735 last = MAX(last, disk_last_activity[sd_map[i]]);
736 return last;
752} 737}
753 738
754void sd_enable(bool on) 739void sd_enable(bool on)
@@ -758,12 +743,12 @@ void sd_enable(bool on)
758 743
759int sd_read_sectors(IF_MD2(int sd_drive,) unsigned long start, int count, void *buf) 744int sd_read_sectors(IF_MD2(int sd_drive,) unsigned long start, int count, void *buf)
760{ 745{
761 return sdmmc_read_sectors(sd_map[sd_drive], start, count, buf); 746 return transfer_sectors(sd_map[sd_drive], start, count, buf, true);
762} 747}
763 748
764int sd_write_sectors(IF_MD2(int sd_drive,) unsigned long start, int count, const void* buf) 749int sd_write_sectors(IF_MD2(int sd_drive,) unsigned long start, int count, const void* buf)
765{ 750{
766 return sdmmc_write_sectors(sd_map[sd_drive], start, count, buf); 751 return transfer_sectors(sd_map[sd_drive], start, count, (void *)buf, false);
767} 752}
768#endif 753#endif
769 754
@@ -778,7 +763,7 @@ int mmc_init(void)
778 if(SDMMC_MODE(drive) == MMC_MODE) 763 if(SDMMC_MODE(drive) == MMC_MODE)
779 { 764 {
780 mmc_map[_mmc_num_drives++] = drive; 765 mmc_map[_mmc_num_drives++] = drive;
781 sdmmc_init_drive(drive); 766 init_drive(drive);
782 } 767 }
783 return 0; 768 return 0;
784} 769}
@@ -811,7 +796,10 @@ bool mmc_removable(IF_MV_NONVOID(int mmc_drive))
811 796
812long mmc_last_disk_activity(void) 797long mmc_last_disk_activity(void)
813{ 798{
814 return _mmc_last_disk_activity; 799 long last = 0;
800 for(unsigned i = 0; i < _mmc_num_drives; i++)
801 last = MAX(last, disk_last_activity[mmc_map[i]]);
802 return last;
815} 803}
816 804
817void mmc_enable(bool on) 805void mmc_enable(bool on)
@@ -863,12 +851,12 @@ int mmc_spinup_time(void)
863 851
864int mmc_read_sectors(IF_MD2(int mmc_drive,) unsigned long start, int count, void *buf) 852int mmc_read_sectors(IF_MD2(int mmc_drive,) unsigned long start, int count, void *buf)
865{ 853{
866 return sdmmc_read_sectors(mmc_map[mmc_drive], start, count, buf); 854 return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true);
867} 855}
868 856
869int mmc_write_sectors(IF_MD2(int mmc_drive,) unsigned long start, int count, const void* buf) 857int mmc_write_sectors(IF_MD2(int mmc_drive,) unsigned long start, int count, const void* buf)
870{ 858{
871 return sdmmc_write_sectors(mmc_map[mmc_drive], start, count, buf); 859 return transfer_sectors(mmc_map[mmc_drive], start, count, (void *)buf, false);
872} 860}
873 861
874#endif 862#endif