summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233
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
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')
-rw-r--r--firmware/target/arm/imx233/debug-imx233.c62
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c71
2 files changed, 127 insertions, 6 deletions
diff --git a/firmware/target/arm/imx233/debug-imx233.c b/firmware/target/arm/imx233/debug-imx233.c
index edb84b990a..2d0150e33d 100644
--- a/firmware/target/arm/imx233/debug-imx233.c
+++ b/firmware/target/arm/imx233/debug-imx233.c
@@ -43,6 +43,8 @@
43#include "stdio.h" 43#include "stdio.h"
44#include "button.h" 44#include "button.h"
45#include "button-imx233.h" 45#include "button-imx233.h"
46#include "sdmmc-imx233.h"
47#include "storage.h"
46 48
47#include "regs/usbphy.h" 49#include "regs/usbphy.h"
48#include "regs/timrot.h" 50#include "regs/timrot.h"
@@ -1190,6 +1192,65 @@ bool dbg_hw_info_button(void)
1190 } 1192 }
1191} 1193}
1192 1194
1195bool dbg_hw_info_sdmmc(void)
1196{
1197 lcd_setfont(FONT_SYSFIXED);
1198
1199 while(1)
1200 {
1201 int button = my_get_action(HZ / 10);
1202 switch(button)
1203 {
1204 case ACT_NEXT:
1205 case ACT_PREV:
1206 case ACT_OK:
1207 lcd_setfont(FONT_UI);
1208 return true;
1209 case ACT_CANCEL:
1210 lcd_setfont(FONT_UI);
1211 return false;
1212 }
1213
1214 lcd_clear_display();
1215 int line = 0;
1216#if CONFIG_STORAGE & STORAGE_MMC
1217 int mmc_idx = 0;
1218#endif
1219#if CONFIG_STORAGE & STORAGE_SD
1220 int sd_idx = 0;
1221#endif
1222 for(int drive = 0; drive < storage_num_drives(); drive++)
1223 {
1224 struct sdmmc_info_t info;
1225 if(false) {}
1226#if CONFIG_STORAGE & STORAGE_MMC
1227 else if(storage_driver_type(drive) == STORAGE_MMC_NUM)
1228 info = imx233_mmc_get_info(mmc_idx++);
1229#endif
1230#if CONFIG_STORAGE & STORAGE_SD
1231 else if(storage_driver_type(drive) == STORAGE_SD_NUM)
1232 info = imx233_sd_get_info(sd_idx++);
1233#endif
1234 else
1235 continue;
1236 lcd_putsf(0, line++, "%s", info.slot_name);
1237#ifdef HAVE_HOTSWAP
1238 bool removable = storage_removable(info.drive);
1239 bool present = storage_present(info.drive);
1240 if(removable)
1241 lcd_putsf(0, line++, " removable %spresent", present ? "" : "not ");
1242 if(!present)
1243 continue;
1244#endif
1245 lcd_putsf(0, line++, " bus: %d sbc: %d", info.bus_width, info.has_sbc);
1246 lcd_putsf(0, line++, " hs: %s", info.hs_enabled ? "enabled" :
1247 info.hs_capable ? "disabled" : "not capable");
1248 }
1249 lcd_update();
1250 yield();
1251 }
1252}
1253
1193static struct 1254static struct
1194{ 1255{
1195 const char *name; 1256 const char *name;
@@ -1215,6 +1276,7 @@ static struct
1215 {"audio", dbg_hw_info_audio}, 1276 {"audio", dbg_hw_info_audio},
1216 {"timrot", dbg_hw_info_timrot}, 1277 {"timrot", dbg_hw_info_timrot},
1217 {"button", dbg_hw_info_button}, 1278 {"button", dbg_hw_info_button},
1279 {"sdmmc", dbg_hw_info_sdmmc},
1218 {"target", dbg_hw_target_info}, 1280 {"target", dbg_hw_target_info},
1219}; 1281};
1220 1282
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