forked from len0rd/rockbox
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
This commit is contained in:
parent
7aacf4da2d
commit
85ad99ee3d
2 changed files with 127 additions and 6 deletions
|
@ -43,6 +43,8 @@
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "button-imx233.h"
|
#include "button-imx233.h"
|
||||||
|
#include "sdmmc-imx233.h"
|
||||||
|
#include "storage.h"
|
||||||
|
|
||||||
#include "regs/usbphy.h"
|
#include "regs/usbphy.h"
|
||||||
#include "regs/timrot.h"
|
#include "regs/timrot.h"
|
||||||
|
@ -1190,6 +1192,65 @@ bool dbg_hw_info_button(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dbg_hw_info_sdmmc(void)
|
||||||
|
{
|
||||||
|
lcd_setfont(FONT_SYSFIXED);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int button = my_get_action(HZ / 10);
|
||||||
|
switch(button)
|
||||||
|
{
|
||||||
|
case ACT_NEXT:
|
||||||
|
case ACT_PREV:
|
||||||
|
case ACT_OK:
|
||||||
|
lcd_setfont(FONT_UI);
|
||||||
|
return true;
|
||||||
|
case ACT_CANCEL:
|
||||||
|
lcd_setfont(FONT_UI);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd_clear_display();
|
||||||
|
int line = 0;
|
||||||
|
#if CONFIG_STORAGE & STORAGE_MMC
|
||||||
|
int mmc_idx = 0;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_STORAGE & STORAGE_SD
|
||||||
|
int sd_idx = 0;
|
||||||
|
#endif
|
||||||
|
for(int drive = 0; drive < storage_num_drives(); drive++)
|
||||||
|
{
|
||||||
|
struct sdmmc_info_t info;
|
||||||
|
if(false) {}
|
||||||
|
#if CONFIG_STORAGE & STORAGE_MMC
|
||||||
|
else if(storage_driver_type(drive) == STORAGE_MMC_NUM)
|
||||||
|
info = imx233_mmc_get_info(mmc_idx++);
|
||||||
|
#endif
|
||||||
|
#if CONFIG_STORAGE & STORAGE_SD
|
||||||
|
else if(storage_driver_type(drive) == STORAGE_SD_NUM)
|
||||||
|
info = imx233_sd_get_info(sd_idx++);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
lcd_putsf(0, line++, "%s", info.slot_name);
|
||||||
|
#ifdef HAVE_HOTSWAP
|
||||||
|
bool removable = storage_removable(info.drive);
|
||||||
|
bool present = storage_present(info.drive);
|
||||||
|
if(removable)
|
||||||
|
lcd_putsf(0, line++, " removable %spresent", present ? "" : "not ");
|
||||||
|
if(!present)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
lcd_putsf(0, line++, " bus: %d sbc: %d", info.bus_width, info.has_sbc);
|
||||||
|
lcd_putsf(0, line++, " hs: %s", info.hs_enabled ? "enabled" :
|
||||||
|
info.hs_capable ? "disabled" : "not capable");
|
||||||
|
}
|
||||||
|
lcd_update();
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -1215,6 +1276,7 @@ static struct
|
||||||
{"audio", dbg_hw_info_audio},
|
{"audio", dbg_hw_info_audio},
|
||||||
{"timrot", dbg_hw_info_timrot},
|
{"timrot", dbg_hw_info_timrot},
|
||||||
{"button", dbg_hw_info_button},
|
{"button", dbg_hw_info_button},
|
||||||
|
{"sdmmc", dbg_hw_info_sdmmc},
|
||||||
{"target", dbg_hw_target_info},
|
{"target", dbg_hw_target_info},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#error SD/MMC mismatch
|
#error SD/MMC mismatch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* static configuration */
|
||||||
struct sdmmc_config_t
|
struct sdmmc_config_t
|
||||||
{
|
{
|
||||||
const char *name; /* name(for debug) */
|
const char *name; /* name(for debug) */
|
||||||
|
@ -85,7 +86,7 @@ struct sdmmc_config_t
|
||||||
#define PIN2BANK(v) ((v) >> 5)
|
#define PIN2BANK(v) ((v) >> 5)
|
||||||
#define PIN2PIN(v) ((v) & 0x1f)
|
#define PIN2PIN(v) ((v) & 0x1f)
|
||||||
|
|
||||||
struct sdmmc_config_t sdmmc_config[] =
|
const struct sdmmc_config_t sdmmc_config[] =
|
||||||
{
|
{
|
||||||
#ifdef SANSA_FUZEPLUS
|
#ifdef SANSA_FUZEPLUS
|
||||||
/* The Fuze+ uses pin #B0P8 for power */
|
/* The Fuze+ uses pin #B0P8 for power */
|
||||||
|
@ -181,6 +182,15 @@ struct sdmmc_config_t sdmmc_config[] =
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* drive status */
|
||||||
|
struct sdmmc_status_t
|
||||||
|
{
|
||||||
|
int bus_width; /* bus width (1, 4 or 8) */
|
||||||
|
bool hs_capable; /* HS capable device */
|
||||||
|
bool hs_enabled; /* HS enabled */
|
||||||
|
bool has_sbc; /* support SET_BLOCK_COUNT */
|
||||||
|
};
|
||||||
|
|
||||||
#define SDMMC_NUM_DRIVES (sizeof(sdmmc_config) / sizeof(sdmmc_config[0]))
|
#define SDMMC_NUM_DRIVES (sizeof(sdmmc_config) / sizeof(sdmmc_config[0]))
|
||||||
|
|
||||||
#define SDMMC_CONF(drive) sdmmc_config[drive]
|
#define SDMMC_CONF(drive) sdmmc_config[drive]
|
||||||
|
@ -200,11 +210,12 @@ static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR;
|
||||||
static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
|
static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
|
||||||
static struct mutex mutex[SDMMC_NUM_DRIVES];
|
static struct mutex mutex[SDMMC_NUM_DRIVES];
|
||||||
static int disk_last_activity[SDMMC_NUM_DRIVES];
|
static int disk_last_activity[SDMMC_NUM_DRIVES];
|
||||||
static bool support_set_block_count[SDMMC_NUM_DRIVES];
|
static struct sdmmc_status_t sdmmc_status[SDMMC_NUM_DRIVES];
|
||||||
#define MIN_YIELD_PERIOD 5
|
#define MIN_YIELD_PERIOD 5
|
||||||
|
|
||||||
#define SDMMC_INFO(drive) sdmmc_card_info[drive]
|
#define SDMMC_INFO(drive) sdmmc_card_info[drive]
|
||||||
#define SDMMC_RCA(drive) SDMMC_INFO(drive).rca
|
#define SDMMC_RCA(drive) SDMMC_INFO(drive).rca
|
||||||
|
#define SDMMC_STATUS(drive) sdmmc_status[drive]
|
||||||
|
|
||||||
/* sd only */
|
/* sd only */
|
||||||
static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
|
static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
|
||||||
|
@ -425,6 +436,7 @@ static int init_sd_card(int drive)
|
||||||
|
|
||||||
/* Switch to 4-bit */
|
/* Switch to 4-bit */
|
||||||
imx233_ssp_set_bus_width(ssp, 4);
|
imx233_ssp_set_bus_width(ssp, 4);
|
||||||
|
SDMMC_STATUS(drive).bus_width = 4;
|
||||||
|
|
||||||
/* Try to switch V2 cards to HS timings, non HS seem to ignore this */
|
/* Try to switch V2 cards to HS timings, non HS seem to ignore this */
|
||||||
if(sd_v2)
|
if(sd_v2)
|
||||||
|
@ -441,7 +453,7 @@ static int init_sd_card(int drive)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* probe for CMD23 support */
|
/* probe for CMD23 support */
|
||||||
support_set_block_count[drive] = false;
|
SDMMC_STATUS(drive).has_sbc = false;
|
||||||
/* ACMD51, only transfer 8 bytes */
|
/* ACMD51, only transfer 8 bytes */
|
||||||
imx233_ssp_set_block_size(ssp, /*log2(8)*/3);
|
imx233_ssp_set_block_size(ssp, /*log2(8)*/3);
|
||||||
if(send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, &resp))
|
if(send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, &resp))
|
||||||
|
@ -450,7 +462,7 @@ static int init_sd_card(int drive)
|
||||||
aligned_buffer[drive], 1, true, true, NULL) == SSP_SUCCESS)
|
aligned_buffer[drive], 1, true, true, NULL) == SSP_SUCCESS)
|
||||||
{
|
{
|
||||||
if(aligned_buffer[drive][3] & 2)
|
if(aligned_buffer[drive][3] & 2)
|
||||||
support_set_block_count[drive] = true;
|
SDMMC_STATUS(drive).has_sbc = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imx233_ssp_set_block_size(ssp, /*log2(512)*/9);
|
imx233_ssp_set_block_size(ssp, /*log2(512)*/9);
|
||||||
|
@ -458,6 +470,8 @@ static int init_sd_card(int drive)
|
||||||
/* SSPCLK @ 96MHz
|
/* SSPCLK @ 96MHz
|
||||||
* gives bitrate of 96 / 4 / 1 = 24MHz
|
* gives bitrate of 96 / 4 / 1 = 24MHz
|
||||||
* gives bitrate of 96 / 2 / 1 = 48MHz */
|
* gives bitrate of 96 / 2 / 1 = 48MHz */
|
||||||
|
SDMMC_STATUS(drive).hs_capable = sd_hs;
|
||||||
|
SDMMC_STATUS(drive).hs_enabled = false;
|
||||||
if(/*sd_hs*/false)
|
if(/*sd_hs*/false)
|
||||||
imx233_ssp_set_timings(ssp, 2, 0, 0xffff);
|
imx233_ssp_set_timings(ssp, 2, 0, 0xffff);
|
||||||
else
|
else
|
||||||
|
@ -534,6 +548,9 @@ static int init_mmc_drive(int drive)
|
||||||
/* SSPCLK @ 96MHz
|
/* SSPCLK @ 96MHz
|
||||||
* gives bitrate of 96 / 2 / 1 = 48MHz */
|
* gives bitrate of 96 / 2 / 1 = 48MHz */
|
||||||
imx233_ssp_set_timings(ssp, 2, 0, 0xffff);
|
imx233_ssp_set_timings(ssp, 2, 0, 0xffff);
|
||||||
|
SDMMC_STATUS(drive).bus_width = 8;
|
||||||
|
SDMMC_STATUS(drive).hs_capable = true;
|
||||||
|
SDMMC_STATUS(drive).hs_enabled = true;
|
||||||
|
|
||||||
/* read extended CSD */
|
/* read extended CSD */
|
||||||
{
|
{
|
||||||
|
@ -549,7 +566,7 @@ static int init_mmc_drive(int drive)
|
||||||
return -13;
|
return -13;
|
||||||
|
|
||||||
/* MMC always support CMD23 */
|
/* MMC always support CMD23 */
|
||||||
support_set_block_count[drive] = false;
|
SDMMC_STATUS(drive).has_sbc = false;
|
||||||
SDMMC_INFO(drive).initialized = 1;
|
SDMMC_INFO(drive).initialized = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -565,7 +582,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
|
||||||
{
|
{
|
||||||
int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512);
|
int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512);
|
||||||
bool need_stop = true;
|
bool need_stop = true;
|
||||||
if(support_set_block_count[drive] && send_cmd(drive, 23, this_count, MCI_RESP, &resp))
|
if(SDMMC_STATUS(drive).has_sbc && send_cmd(drive, 23, this_count, MCI_RESP, &resp))
|
||||||
need_stop = false;
|
need_stop = false;
|
||||||
/* Set bank_start to the correct unit (blocks or bytes).
|
/* Set bank_start to the correct unit (blocks or bytes).
|
||||||
* MMC drives use block addressing, SD cards bytes or blocks */
|
* MMC drives use block addressing, SD cards bytes or blocks */
|
||||||
|
@ -1070,3 +1087,45 @@ tCardInfo *mmc_card_info(int card_no)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Information about SD/MMC slot */
|
||||||
|
struct sdmmc_info_t
|
||||||
|
{
|
||||||
|
int drive; /* drive number (for queries like storage_removable(drive) */
|
||||||
|
const char *slot_name; /* name of the slot: 'internal' or 'microsd' */
|
||||||
|
bool window; /* is window enabled for this slot? */
|
||||||
|
int bus_width; /* current bus width */
|
||||||
|
bool hs_capable; /* is device high-speed capable? */
|
||||||
|
bool hs_enabled; /* is high-speed enabled? */
|
||||||
|
bool has_sbc; /* device support SET_BLOCK_COUNT */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sdmmc_info_t imx233_sdmmc_get_info(int drive, int storage_drive)
|
||||||
|
{
|
||||||
|
struct sdmmc_info_t info;
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.drive = storage_drive;
|
||||||
|
info.slot_name = SDMMC_CONF(drive).name;
|
||||||
|
info.window = !!(SDMMC_CONF(drive).flags & WINDOW);
|
||||||
|
info.bus_width = SDMMC_STATUS(drive).bus_width;
|
||||||
|
info.hs_capable = SDMMC_STATUS(drive).hs_capable;
|
||||||
|
info.hs_enabled = SDMMC_STATUS(drive).hs_enabled;
|
||||||
|
info.has_sbc = SDMMC_STATUS(drive).has_sbc;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_STORAGE & STORAGE_SD
|
||||||
|
/* return information about a particular sd device (use regular drive number) */
|
||||||
|
struct sdmmc_info_t imx233_sd_get_info(int card_no)
|
||||||
|
{
|
||||||
|
return imx233_sdmmc_get_info(sd_map[card_no], sd_first_drive + card_no);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_STORAGE & STORAGE_MMC
|
||||||
|
/* return information about a particular mmc device (use regular drive number) */
|
||||||
|
struct sdmmc_info_t imx233_mmc_get_info(int card_no)
|
||||||
|
{
|
||||||
|
return imx233_sdmmc_get_info(mmc_map[card_no], mmc_first_drive + card_no);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue