summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/sdmmc-imx233.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-05-29 16:07:43 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2016-05-29 16:07:43 +0100
commit85ad99ee3d5eaae6e98f958c5aed5d3d36ca460a (patch)
tree2b2e6065b3185780e2c19ee9936f4f0a0e37f54d /firmware/target/arm/imx233/sdmmc-imx233.c
parent7aacf4da2dacf649e69139e53405e2e6a9a2cbb6 (diff)
downloadrockbox-85ad99ee3d5eaae6e98f958c5aed5d3d36ca460a.tar.gz
rockbox-85ad99ee3d5eaae6e98f958c5aed5d3d36ca460a.zip
imx233: add sd/mmc debug screen
The screen currently displays for each device the bus width, set_block_count support, HS capability and whether it is enabled for not. Change-Id: I6b1c3b1019e55ef1097a23c1f54fb07f5c7aa3b0
Diffstat (limited to 'firmware/target/arm/imx233/sdmmc-imx233.c')
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c71
1 files changed, 65 insertions, 6 deletions
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index 4296720810..13ef1b8375 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -55,6 +55,7 @@
55#error SD/MMC mismatch 55#error SD/MMC mismatch
56#endif 56#endif
57 57
58/* static configuration */
58struct sdmmc_config_t 59struct sdmmc_config_t
59{ 60{
60 const char *name; /* name(for debug) */ 61 const char *name; /* name(for debug) */
@@ -85,7 +86,7 @@ struct sdmmc_config_t
85#define PIN2BANK(v) ((v) >> 5) 86#define PIN2BANK(v) ((v) >> 5)
86#define PIN2PIN(v) ((v) & 0x1f) 87#define PIN2PIN(v) ((v) & 0x1f)
87 88
88struct sdmmc_config_t sdmmc_config[] = 89const struct sdmmc_config_t sdmmc_config[] =
89{ 90{
90#ifdef SANSA_FUZEPLUS 91#ifdef SANSA_FUZEPLUS
91 /* The Fuze+ uses pin #B0P8 for power */ 92 /* The Fuze+ uses pin #B0P8 for power */
@@ -181,6 +182,15 @@ struct sdmmc_config_t sdmmc_config[] =
181#endif 182#endif
182}; 183};
183 184
185/* drive status */
186struct sdmmc_status_t
187{
188 int bus_width; /* bus width (1, 4 or 8) */
189 bool hs_capable; /* HS capable device */
190 bool hs_enabled; /* HS enabled */
191 bool has_sbc; /* support SET_BLOCK_COUNT */
192};
193
184#define SDMMC_NUM_DRIVES (sizeof(sdmmc_config) / sizeof(sdmmc_config[0])) 194#define SDMMC_NUM_DRIVES (sizeof(sdmmc_config) / sizeof(sdmmc_config[0]))
185 195
186#define SDMMC_CONF(drive) sdmmc_config[drive] 196#define SDMMC_CONF(drive) sdmmc_config[drive]
@@ -200,11 +210,12 @@ static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR;
200static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; 210static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
201static struct mutex mutex[SDMMC_NUM_DRIVES]; 211static struct mutex mutex[SDMMC_NUM_DRIVES];
202static int disk_last_activity[SDMMC_NUM_DRIVES]; 212static int disk_last_activity[SDMMC_NUM_DRIVES];
203static bool support_set_block_count[SDMMC_NUM_DRIVES]; 213static struct sdmmc_status_t sdmmc_status[SDMMC_NUM_DRIVES];
204#define MIN_YIELD_PERIOD 5 214#define MIN_YIELD_PERIOD 5
205 215
206#define SDMMC_INFO(drive) sdmmc_card_info[drive] 216#define SDMMC_INFO(drive) sdmmc_card_info[drive]
207#define SDMMC_RCA(drive) SDMMC_INFO(drive).rca 217#define SDMMC_RCA(drive) SDMMC_INFO(drive).rca
218#define SDMMC_STATUS(drive) sdmmc_status[drive]
208 219
209/* sd only */ 220/* sd only */
210static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 221static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
@@ -425,6 +436,7 @@ static int init_sd_card(int drive)
425 436
426 /* Switch to 4-bit */ 437 /* Switch to 4-bit */
427 imx233_ssp_set_bus_width(ssp, 4); 438 imx233_ssp_set_bus_width(ssp, 4);
439 SDMMC_STATUS(drive).bus_width = 4;
428 440
429 /* Try to switch V2 cards to HS timings, non HS seem to ignore this */ 441 /* Try to switch V2 cards to HS timings, non HS seem to ignore this */
430 if(sd_v2) 442 if(sd_v2)
@@ -441,7 +453,7 @@ static int init_sd_card(int drive)
441 } 453 }
442 454
443 /* probe for CMD23 support */ 455 /* probe for CMD23 support */
444 support_set_block_count[drive] = false; 456 SDMMC_STATUS(drive).has_sbc = false;
445 /* ACMD51, only transfer 8 bytes */ 457 /* ACMD51, only transfer 8 bytes */
446 imx233_ssp_set_block_size(ssp, /*log2(8)*/3); 458 imx233_ssp_set_block_size(ssp, /*log2(8)*/3);
447 if(send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, &resp)) 459 if(send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, &resp))
@@ -450,7 +462,7 @@ static int init_sd_card(int drive)
450 aligned_buffer[drive], 1, true, true, NULL) == SSP_SUCCESS) 462 aligned_buffer[drive], 1, true, true, NULL) == SSP_SUCCESS)
451 { 463 {
452 if(aligned_buffer[drive][3] & 2) 464 if(aligned_buffer[drive][3] & 2)
453 support_set_block_count[drive] = true; 465 SDMMC_STATUS(drive).has_sbc = true;
454 } 466 }
455 } 467 }
456 imx233_ssp_set_block_size(ssp, /*log2(512)*/9); 468 imx233_ssp_set_block_size(ssp, /*log2(512)*/9);
@@ -458,6 +470,8 @@ static int init_sd_card(int drive)
458 /* SSPCLK @ 96MHz 470 /* SSPCLK @ 96MHz
459 * gives bitrate of 96 / 4 / 1 = 24MHz 471 * gives bitrate of 96 / 4 / 1 = 24MHz
460 * gives bitrate of 96 / 2 / 1 = 48MHz */ 472 * gives bitrate of 96 / 2 / 1 = 48MHz */
473 SDMMC_STATUS(drive).hs_capable = sd_hs;
474 SDMMC_STATUS(drive).hs_enabled = false;
461 if(/*sd_hs*/false) 475 if(/*sd_hs*/false)
462 imx233_ssp_set_timings(ssp, 2, 0, 0xffff); 476 imx233_ssp_set_timings(ssp, 2, 0, 0xffff);
463 else 477 else
@@ -534,6 +548,9 @@ static int init_mmc_drive(int drive)
534 /* SSPCLK @ 96MHz 548 /* SSPCLK @ 96MHz
535 * gives bitrate of 96 / 2 / 1 = 48MHz */ 549 * gives bitrate of 96 / 2 / 1 = 48MHz */
536 imx233_ssp_set_timings(ssp, 2, 0, 0xffff); 550 imx233_ssp_set_timings(ssp, 2, 0, 0xffff);
551 SDMMC_STATUS(drive).bus_width = 8;
552 SDMMC_STATUS(drive).hs_capable = true;
553 SDMMC_STATUS(drive).hs_enabled = true;
537 554
538 /* read extended CSD */ 555 /* read extended CSD */
539 { 556 {
@@ -549,7 +566,7 @@ static int init_mmc_drive(int drive)
549 return -13; 566 return -13;
550 567
551 /* MMC always support CMD23 */ 568 /* MMC always support CMD23 */
552 support_set_block_count[drive] = false; 569 SDMMC_STATUS(drive).has_sbc = false;
553 SDMMC_INFO(drive).initialized = 1; 570 SDMMC_INFO(drive).initialized = 1;
554 571
555 return 0; 572 return 0;
@@ -565,7 +582,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
565 { 582 {
566 int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512); 583 int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512);
567 bool need_stop = true; 584 bool need_stop = true;
568 if(support_set_block_count[drive] && send_cmd(drive, 23, this_count, MCI_RESP, &resp)) 585 if(SDMMC_STATUS(drive).has_sbc && send_cmd(drive, 23, this_count, MCI_RESP, &resp))
569 need_stop = false; 586 need_stop = false;
570 /* Set bank_start to the correct unit (blocks or bytes). 587 /* Set bank_start to the correct unit (blocks or bytes).
571 * MMC drives use block addressing, SD cards bytes or blocks */ 588 * MMC drives use block addressing, SD cards bytes or blocks */
@@ -1070,3 +1087,45 @@ tCardInfo *mmc_card_info(int card_no)
1070} 1087}
1071 1088
1072#endif 1089#endif
1090
1091/** Information about SD/MMC slot */
1092struct sdmmc_info_t
1093{
1094 int drive; /* drive number (for queries like storage_removable(drive) */
1095 const char *slot_name; /* name of the slot: 'internal' or 'microsd' */
1096 bool window; /* is window enabled for this slot? */
1097 int bus_width; /* current bus width */
1098 bool hs_capable; /* is device high-speed capable? */
1099 bool hs_enabled; /* is high-speed enabled? */
1100 bool has_sbc; /* device support SET_BLOCK_COUNT */
1101};
1102
1103struct sdmmc_info_t imx233_sdmmc_get_info(int drive, int storage_drive)
1104{
1105 struct sdmmc_info_t info;
1106 memset(&info, 0, sizeof(info));
1107 info.drive = storage_drive;
1108 info.slot_name = SDMMC_CONF(drive).name;
1109 info.window = !!(SDMMC_CONF(drive).flags & WINDOW);
1110 info.bus_width = SDMMC_STATUS(drive).bus_width;
1111 info.hs_capable = SDMMC_STATUS(drive).hs_capable;
1112 info.hs_enabled = SDMMC_STATUS(drive).hs_enabled;
1113 info.has_sbc = SDMMC_STATUS(drive).has_sbc;
1114 return info;
1115}
1116
1117#if CONFIG_STORAGE & STORAGE_SD
1118/* return information about a particular sd device (use regular drive number) */
1119struct sdmmc_info_t imx233_sd_get_info(int card_no)
1120{
1121 return imx233_sdmmc_get_info(sd_map[card_no], sd_first_drive + card_no);
1122}
1123#endif
1124
1125#if CONFIG_STORAGE & STORAGE_MMC
1126/* return information about a particular mmc device (use regular drive number) */
1127struct sdmmc_info_t imx233_mmc_get_info(int card_no)
1128{
1129 return imx233_sdmmc_get_info(mmc_map[card_no], mmc_first_drive + card_no);
1130}
1131#endif