summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-08-21 16:25:11 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2012-08-21 16:28:36 +0200
commit41bf9ebc89415380751f2d457db5afac0c824369 (patch)
tree5c6b4a57532fefd853e01fd721fccec1d87857d1 /firmware/target
parent39396cc70752748c3fbafa6a0afc26835719b9e4 (diff)
downloadrockbox-41bf9ebc89415380751f2d457db5afac0c824369.tar.gz
rockbox-41bf9ebc89415380751f2d457db5afac0c824369.zip
imx233: simplify sd/mmc driver
Further merge drivers by using the same command and data functions. No use one mutex per drive instead of a global sd lock. Fix the RCA handling which was different between SD and MMC (shifted 16) and thus confusing. Add MMC commands definition to the mmc.h header similarly to the SD one. Change MMC handling a bit by selecting/deselecting on each transfer like SD, which allows for several MMC devices in theory and is more uniform. Change-Id: I7024cb19c079553806138ead75b00640f1d2d95c
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c368
1 files changed, 178 insertions, 190 deletions
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