This is an automated email from the ASF dual-hosted git repository.
davids5 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 50a8ec62c4 Add eMMC driver support
50a8ec62c4 is described below
commit 50a8ec62c45dc12512cbbd5dce7f1e885b003849
Author: Radek Pesina <[email protected]>
AuthorDate: Wed Mar 29 11:04:50 2023 +1100
Add eMMC driver support
- Fix DMA addressing issues within litex_sendsetup/litex_recvsetup
- Extend with handling specific to eMMC commands during init & use.
- Cleanup of 4-bit BUS handling for SD and eMMC
- For eMMC, Send CMD0 during init as per JEDEC v4.41 for pre-idle
---
arch/risc-v/src/litex/litex_sdio.c | 8 +-
boards/risc-v/litex/arty_a7/Kconfig | 38 ++++
.../risc-v/litex/arty_a7/configs/sdmmc/defconfig | 75 ++++++++
drivers/mmcsd/mmcsd_sdio.c | 200 ++++++++++++++++++---
drivers/mmcsd/mmcsd_sdio.h | 26 +++
5 files changed, 316 insertions(+), 31 deletions(-)
diff --git a/arch/risc-v/src/litex/litex_sdio.c
b/arch/risc-v/src/litex/litex_sdio.c
index 13359662a3..eec66ed295 100644
--- a/arch/risc-v/src/litex/litex_sdio.c
+++ b/arch/risc-v/src/litex/litex_sdio.c
@@ -860,10 +860,12 @@ static int litex_recvsetup(struct sdio_dev_s *dev,
uint8_t *buffer,
/* flush CPU d-cache */
+#ifndef CONFIG_LITEX_COHERENT_DMA
up_invalidate_dcache_all();
+#endif
putreg32(0, LITEX_SDBLOCK2MEM_DMA_ENABLE);
- putreg32((uintptr_t)buffer >> 32, LITEX_SDBLOCK2MEM_DMA_BASE);
+ putreg32((uintptr_t)(&buffer[4]), LITEX_SDBLOCK2MEM_DMA_BASE);
putreg32((uintptr_t)buffer, LITEX_SDBLOCK2MEM_DMA_BASE + 0x04);
putreg32(nbytes, LITEX_SDBLOCK2MEM_DMA_LENGTH);
putreg32(1, LITEX_SDBLOCK2MEM_DMA_ENABLE);
@@ -903,10 +905,12 @@ static int litex_sendsetup(struct sdio_dev_s *dev,
/* flush CPU d-cache */
+#ifndef CONFIG_LITEX_COHERENT_DMA
up_invalidate_dcache_all();
+#endif
putreg32(0, LITEX_SDMEM2BLOCK_DMA_ENABLE);
- putreg32((uintptr_t)buffer >> 32, LITEX_SDMEM2BLOCK_DMA_BASE);
+ putreg32((uintptr_t)(&buffer[4]), LITEX_SDMEM2BLOCK_DMA_BASE);
putreg32((uintptr_t)buffer, LITEX_SDMEM2BLOCK_DMA_BASE + 0x04);
putreg32(nbytes, LITEX_SDMEM2BLOCK_DMA_LENGTH);
putreg32(1, LITEX_SDMEM2BLOCK_DMA_ENABLE);
diff --git a/boards/risc-v/litex/arty_a7/Kconfig
b/boards/risc-v/litex/arty_a7/Kconfig
index 92df0ad54c..b64aa2d566 100644
--- a/boards/risc-v/litex/arty_a7/Kconfig
+++ b/boards/risc-v/litex/arty_a7/Kconfig
@@ -5,6 +5,44 @@
if ARCH_BOARD_ARTY_A7
+
+config LITEX_SDIO
+ bool "SDIO"
+ default n
+ select SCHED_HPWORK
+ select MMCSD
+ select MMCSD_SDIO
+ select SDIO_BLOCKSETUP
+ select ARCH_HAVE_SDIO
+ select SDIO_DMA
+
+config LITEX_SDIO1
+ bool "Enable SDIO1"
+ default y if LITEX_SDIO
+ select LITEX_SDIO_DMA
+ depends on LITEX_SDIO
+
+config LITEX_IDMODE_FREQ
+ int "ID mode frequency"
+ default 400000
+ depends on LITEX_SDIO
+ ---help---
+ Initial, ID mode SD frequency
+
+config LITEX_MMCXFR_FREQ
+ int "MMC transfer frequency"
+ default 25000000
+ depends on LITEX_SDIO
+ ---help---
+ Frequency to use for transferring data to/from an MMC card
+
+config LITEX_SD4BIT_FREQ
+ int "SD 4-bit transfer frequency"
+ default 50000000
+ depends on LITEX_SDIO
+ ---help---
+ Frequency to use for transferring data to/from an SD card using
all four data lines.
+
config LITEX_SDIO_MOUNT
bool "Mount SDIO at startup"
default n
diff --git a/boards/risc-v/litex/arty_a7/configs/sdmmc/defconfig
b/boards/risc-v/litex/arty_a7/configs/sdmmc/defconfig
new file mode 100644
index 0000000000..3b4d385526
--- /dev/null
+++ b/boards/risc-v/litex/arty_a7/configs/sdmmc/defconfig
@@ -0,0 +1,75 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that
includes your
+# modifications.
+#
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_FS_PROCFS_EXCLUDE_BLOCKS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_ENVIRON is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MEMINFO is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MOUNT is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
+# CONFIG_FS_PROCFS_EXCLUDE_USAGE is not set
+# CONFIG_FS_PROCFS_EXCLUDE_VERSION is not set
+# CONFIG_NSH_DISABLEBG is not set
+# CONFIG_NSH_DISABLE_LOSMART is not set
+# CONFIG_NSH_DISABLE_UNAME is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="arty_a7"
+CONFIG_ARCH_BOARD_ARTY_A7=y
+CONFIG_ARCH_CHIP="litex"
+CONFIG_ARCH_CHIP_LITEX=y
+CONFIG_ARCH_INTERRUPTSTACK=8192
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BINFMT_DISABLE=y
+CONFIG_BOARD_LOOPSPERMSEC=10000
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_SMALL=y
+CONFIG_DEV_ZERO=y
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_EXAMPLES_HELLO_STACKSIZE=8192
+CONFIG_FAT_DMAMEMORY=y
+CONFIG_FAT_FORCE_INDIRECT=y
+CONFIG_FAT_LFN=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FATTIME=y
+CONFIG_FS_PROCFS=y
+CONFIG_GRAN=y
+CONFIG_IDLETHREAD_STACKSIZE=8192
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=8192
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_LITEX_SDIO=y
+CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=64
+CONFIG_NSH_STRERROR=y
+CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=8192
+CONFIG_PTHREAD_STACK_DEFAULT=8192
+CONFIG_RAM_SIZE=268435456
+CONFIG_RAM_START=0x40000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=20
+CONFIG_START_MONTH=3
+CONFIG_START_YEAR=2020
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=12
+CONFIG_TESTING_GETPRIME=y
+CONFIG_UART0_RXBUFSIZE=128
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_UART0_TXBUFSIZE=128
diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c
index 5465ab781e..8569ee6d86 100644
--- a/drivers/mmcsd/mmcsd_sdio.c
+++ b/drivers/mmcsd/mmcsd_sdio.c
@@ -355,6 +355,7 @@ static inline int mmcsd_sendcmd4(FAR struct mmcsd_state_s
*priv)
if (priv->dsrimp != false)
{
+ finfo("Card supports DSR - send DSR.\n");
/* CMD4 = SET_DSR will set the cards DSR register. The DSR and CMD4
* support are optional. However, since this is a broadcast command
* with no response (like CMD0), we will never know if the DSR was
@@ -369,6 +370,10 @@ static inline int mmcsd_sendcmd4(FAR struct mmcsd_state_s
*priv)
mmcsd_sendcmdpoll(priv, MMCSD_CMD4, CONFIG_MMCSD_DSR << 16);
nxsig_usleep(MMCSD_DSR_DELAY);
}
+ else
+ {
+ finfo("Card does not support DSR.\n");
+ }
#endif
return ret;
@@ -2472,9 +2477,14 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
* SCR or in the SDIO driver capabililities)
*/
- if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0 &&
+ if (IS_SD(priv->type) &&
+ (priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0 &&
(priv->caps & SDIO_CAPS_1BIT_ONLY) == 0)
{
+ /* SD card supports 4-bit BUS and host settings is not 1-bit only. */
+
+ finfo("Setting SD BUS width to 4-bit. Card type: %d\n", priv->type);
+
/* Disconnect any CD/DAT3 pull up using ACMD42. ACMD42 is optional and
* need not be supported by all SD calls.
*
@@ -2504,7 +2514,7 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
return ret;
}
- /* Now send ACMD6 to select wide, 4-bit bus operation, beginning
+ /* Now send ACMD6 to select bus width operation, beginning
* with CMD55, APP_CMD:
*/
@@ -2519,27 +2529,82 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
/* Then send ACMD6 */
mmcsd_sendcmdpoll(priv, SD_ACMD6, MMCSD_ACMD6_BUSWIDTH_4);
+
ret = mmcsd_recv_r1(priv, SD_ACMD6);
if (ret != OK)
{
return ret;
}
+ }
+#ifdef CONFIG_MMCSD_MMCSUPPORT
+ else if (IS_MMC(priv->type) &&
+ ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0 &&
+ (priv->caps & SDIO_CAPS_1BIT_ONLY) == 0))
+ {
+ /* SD card supports 4-bit BUS and host settings is not 1-bit only.
+ * Configuring MMC - Use MMC_SWITCH access modes.
+ */
- /* Configure the SDIO peripheral */
+ uint32_t arg = MMCSD_CMD6_MODE_WRITE_BYTE | MMCSD_CMD6_BUSWIDTH_RW;
- finfo("Wide bus operation selected\n");
- SDIO_WIDEBUS(priv->dev, true);
- priv->widebus = true;
+ arg |= MMCSD_CMD6_BUS_WIDTH_4;
- SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD6, arg);
+ ret = mmcsd_recv_r1(priv, MMCSD_CMD6);
+
+ if (ret != OK)
+ {
+ ferr("ERROR: (MMCSD_CMD6) Setting MMC BUS width: %d\n", ret);
+ return ret;
+ }
+ }
+#endif /* #ifdef CONFIG_MMCSD_MMCSUPPORT */
+ else
+ {
+ fwarn("No card inserted.\n");
+ SDIO_WIDEBUS(priv->dev, false);
+ priv->widebus = false;
+ SDIO_CLOCK(priv->dev, CLOCK_SDIO_DISABLED);
nxsig_usleep(MMCSD_CLK_DELAY);
+
return OK;
}
- /* Wide bus operation not supported */
+ /* Configure the SDIO peripheral */
- fwarn("WARNING: Card does not support wide-bus operation\n");
- return -ENOSYS;
+ if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0)
+ {
+ finfo("Wide bus operation selected\n");
+ SDIO_WIDEBUS(priv->dev, true);
+ priv->widebus = true;
+ }
+ else
+ {
+ finfo("Narrow bus operation selected\n");
+ SDIO_WIDEBUS(priv->dev, false);
+ priv->widebus = false;
+ }
+
+ if (IS_SD(priv->type))
+ {
+ if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0)
+ {
+ SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
+ }
+ else
+ {
+ SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_1BIT);
+ }
+ }
+#ifdef CONFIG_MMCSD_MMCSUPPORT
+ else
+ {
+ SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
+ }
+#endif /* #ifdef CONFIG_MMCSD_MMCSUPPORT */
+
+ nxsig_usleep(MMCSD_CLK_DELAY);
+ return OK;
}
/****************************************************************************
@@ -2571,6 +2636,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
* identification state / card-identification mode.
*/
+ finfo("Initialising MMC card.\n");
+
mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0);
ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid);
if (ret != OK)
@@ -2587,7 +2654,7 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
*/
priv->rca = 1; /* There is only one card */
- mmcsd_sendcmdpoll(priv, MMC_CMD3, priv->rca << 16);
+ mmcsd_sendcmdpoll(priv, MMC_CMD3, (uint32_t)priv->rca << 16);
ret = mmcsd_recv_r1(priv, MMC_CMD3);
if (ret != OK)
{
@@ -2597,8 +2664,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
/* This should have caused a transition to standby state. However, this
* will not be reflected in the present R1/6 status. R1/6 contains the
- * state of the card when the command was received, not when it completed
- * execution.
+ * state of the card when the command was received, not when it
+ * completed execution.
*
* Verify that we are in standby state/data-transfer mode
*/
@@ -2612,10 +2679,18 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
/* Send CMD9, SEND_CSD in standby state/data-transfer mode to obtain the
* Card Specific Data (CSD) register, e.g., block length, card storage
- * capacity, etc. (Stays in standby state/data-transfer mode)
+ * capacity, etc. (Stays in standby state/data-transfer mode).
+ * NOTE in v2.0 high capacity cards, the following values are always
+ * returned:
+ * - write block length = 9 = 2^9 = 512
+ * - read block length = 9 = 512
+ * - rw2 factor = 0x2 (010b)
+ * - size_mult = 0
+ * We can't decode the CSD register yet as we also need to read the
+ * extended CSD register.
*/
- mmcsd_sendcmdpoll(priv, MMCSD_CMD9, priv->rca << 16);
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD9, (uint32_t) priv->rca << 16);
ret = SDIO_RECVR2(priv->dev, MMCSD_CMD9, csd);
if (ret != OK)
{
@@ -2623,6 +2698,13 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
return ret;
}
+ /* Decode the CSD register to obtain version. We will need to
+ * decode further if card is v4.0 or higher as it supports
+ * ext_csd commands.
+ */
+
+ mmcsd_decode_csd(priv, csd);
+
/* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been
* provided and (2) the card supports a DSR register. If no DSR value
* the card default value (0x0404) will be used.
@@ -2630,7 +2712,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
mmcsd_sendcmd4(priv);
- /* Send CMD7 with the argument == RCA in order to select the card
+ /* Select the card.
+ * Send CMD7 with the argument == RCA in order to select the card
* and send it in data-trasfer mode. Since we are supporting
* only a single card, we just leave the card selected all of the time.
*/
@@ -2643,14 +2726,33 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
return ret;
}
+ /* If the hardware only supports 4-bit transfer mode then we forced to
+ * attempt to setup the card in this mode before checking the ext CSD
+ * register.
+ */
+
+ if ((priv->caps & SDIO_CAPS_4BIT_ONLY) != 0)
+ {
+ /* Select width (4-bit) bus operation */
+
+ priv->buswidth = MMCSD_SCR_BUSWIDTH_4BIT;
+ ret = mmcsd_widebus(priv);
+
+ if (ret != OK)
+ {
+ ferr("ERROR: Failed to set wide bus operation: %d\n", ret);
+ }
+ }
+
/* CSD Decoding for MMC should be done after entering in data-transfer mode
* because if the card has block addressing then extended CSD register
* must be read in order to get the right number of blocks and capacity,
- * but it has to be done in data-transfer mode.
+ * and BUS width but it has to be done in data-transfer mode.
*/
if (IS_BLOCK(priv->type))
{
+ finfo("Card supports eMMC spec 4.0 (or greater). Reading ext_csd.\n");
ret = mmcsd_read_csd(priv);
if (ret != OK)
{
@@ -2661,10 +2763,17 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s
*priv)
mmcsd_decode_csd(priv, csd);
- /* Select high speed MMC clocking (which may depend on the DSR setting) */
+ if ((priv->caps & SDIO_CAPS_4BIT_ONLY) != 0)
+ {
+ /* Select width (4-bit) bus operation (if the card supports it) */
+
+ ret = mmcsd_widebus(priv);
+ if (ret != OK)
+ {
+ ferr("ERROR: Failed to set wide bus operation: %d\n", ret);
+ }
+ }
- SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
- nxsig_usleep(MMCSD_CLK_DELAY);
return OK;
}
@@ -2698,6 +2807,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv)
memset(buffer, 0, sizeof(buffer));
#if defined(CONFIG_SDIO_DMA) && defined(CONFIG_ARCH_HAVE_SDIO_PREFLIGHT)
+
/* If we think we are going to perform a DMA transfer, make sure that we
* will be able to before we commit the card to the operation.
*/
@@ -2726,7 +2836,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv)
return ret;
}
- /* Select the block size for the card */
+ /* Select the block size for the card (CMD16) */
ret = mmcsd_setblocklen(priv, 512);
if (ret != OK)
@@ -2745,6 +2855,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv)
#ifdef CONFIG_SDIO_DMA
if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0)
{
+ finfo("Setting up for DMA transfer.\n");
ret = SDIO_DMARECVSETUP(priv->dev, buffer, 512);
if (ret != OK)
{
@@ -3274,8 +3385,9 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s
*priv)
{
/* Select width (4-bit) bus operation */
- priv->buswidth = 4;
+ priv->buswidth = MMCSD_SCR_BUSWIDTH_4BIT;
ret = mmcsd_widebus(priv);
+
if (ret != OK)
{
ferr("ERROR: Failed to set wide bus operation: %d\n", ret);
@@ -3296,7 +3408,7 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s
*priv)
mmcsd_decode_scr(priv, scr);
- if ((priv->caps & SDIO_CAPS_4BIT_ONLY) == 0)
+ if ((priv->caps & SDIO_CAPS_4BIT_ONLY) != 0)
{
/* Select width (4-bit) bus operation (if the card supports it) */
@@ -3335,6 +3447,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
clock_t elapsed;
int ret;
+ finfo("Identifying card...\n");
+
/* Assume failure to identify the card */
priv->type = MMCSD_CARDTYPE_UNKNOWN;
@@ -3349,6 +3463,13 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
return -ENODEV;
}
+ /* For eMMC, Send CMD0 with argument 0xf0f0f0f0 as per JEDEC v4.41
+ * for pre-idle. No effect for SD.
+ */
+
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0xf0f0f0f0);
+ nxsig_usleep(MMCSD_IDLE_DELAY);
+
/* Set ID mode clocking (<400KHz) */
SDIO_CLOCK(priv->dev, CLOCK_IDMODE);
@@ -3376,12 +3497,14 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
if (ret != OK)
{
- ferr("ERROR: CMD1 RECVR3: %d\n", ret);
+ fwarn("WARNING: CMD1 RECVR3: %d. \
+ NOTE: This is expected for SD cards.\n", ret);
- /* CMD1 did not succeed, card is not MMC. This sleep let
- * the communication to recover before another send.
+ /* CMD1 did not succeed, card is not MMC. Return to idle
+ * to allow the communication to recover before another send.
*/
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0);
nxsig_usleep(MMCSD_IDLE_DELAY);
}
else
@@ -3471,7 +3594,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
}
}
- /* At this point, type is either UNKNOWN or SDV2. Try sending
+ /* At this point, type is either UNKNOWN, eMMC or SDV2. Try sending
* CMD55 and (maybe) ACMD41 for up to 1 second or until the card
* exits the IDLE state. CMD55 is supported by SD V1.x and SD V2.x,
* but not MMC
@@ -3481,7 +3604,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
elapsed = 0;
do
{
- /* We may have already determined that his card is an MMC card from
+ /* We may have already determined that this card is an MMC card from
* an earlier pass through this loop. In that case, we should
* skip the SD-specific commands.
*/
@@ -3602,6 +3725,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
{
/* CMD1 succeeded... this must be an MMC card */
+ finfo("Confirmed MMC card present.\n");
+
priv->type = MMCSD_CARDTYPE_MMC;
/* Now, check if this is a MMC card/chip that supports block
@@ -3633,9 +3758,13 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s
*priv)
* Then break out of the look with an MMC card identified
*/
- finfo("MMC card/chip ready!\n");
+ finfo("MMC card/chip is ready!\n");
break;
}
+ else
+ {
+ finfo("MMC card/chip is busy. Waiting for reply...\n");
+ }
}
}
#endif
@@ -3708,6 +3837,8 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
{
/* Yes.. probe it. First, what kind of card was inserted? */
+ finfo("Card present. Probing....\n");
+
ret = mmcsd_cardidentify(priv);
if (ret != OK)
{
@@ -3722,24 +3853,33 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
/* Bit 1: SD version 1.x */
case MMCSD_CARDTYPE_SDV1:
+ finfo("SD version 1.x .\n");
+ ret = mmcsd_sdinitialize(priv);
+ break;
/* SD version 2.x with byte addressing */
case MMCSD_CARDTYPE_SDV2:
+ finfo("SD version 2.x with byte addressing.\n");
+ ret = mmcsd_sdinitialize(priv);
+ break;
/* SD version 2.x with block addressing */
case MMCSD_CARDTYPE_SDV2 | MMCSD_CARDTYPE_BLOCK:
+ finfo("SD version 2.x with block addressing.\n");
ret = mmcsd_sdinitialize(priv);
break;
/* MMC card with byte addressing */
case MMCSD_CARDTYPE_MMC:
+ finfo("MMC card with byte addressing.\n");
/* MMC card with block addressing */
case MMCSD_CARDTYPE_MMC | MMCSD_CARDTYPE_BLOCK:
+ finfo("MMC card with block addressing.\n");
#ifdef CONFIG_MMCSD_MMCSUPPORT
ret = mmcsd_mmcinitialize(priv);
break;
@@ -3824,8 +3964,10 @@ static int mmcsd_removed(FAR struct mmcsd_state_s *priv)
/* Go back to the default 1-bit data bus. */
+ priv->buswidth = MMCSD_SCR_BUSWIDTH_1BIT;
SDIO_WIDEBUS(priv->dev, false);
priv->widebus = false;
+ mmcsd_widebus(priv);
/* Disable clocking to the card */
diff --git a/drivers/mmcsd/mmcsd_sdio.h b/drivers/mmcsd/mmcsd_sdio.h
index 83e1c445c8..031a81a76d 100644
--- a/drivers/mmcsd/mmcsd_sdio.h
+++ b/drivers/mmcsd/mmcsd_sdio.h
@@ -32,6 +32,32 @@
* Pre-processor Definitions
****************************************************************************/
+/* CMD6 (MMC_SWITCH) argument
+ * MMC_SWITCH argument format:
+ *
+ * [31:26] Always 0
+ * [25:24] Access Mode
+ * [23:16] Location of target Byte in EXT_CSD
+ * [15:08] Value Byte
+ * [07:03] Always 0
+ * [02:00] Command Set
+ */
+#define MMCSD_CMD6_BUSWIDTH_RWSHIFT (16)
+# define MMCSD_CMD6_BUSWIDTH_RW ((uint32_t)0xb7 <<
MMCSD_CMD6_BUSWIDTH_RWSHIFT) /* R/W */
+
+#define MMCSD_CMD6_WRITE_BYTE_SHIFT (24)
+# define MMCSD_CMD6_MODE_CMD_SET ((uint32_t)0x00 <<
MMCSD_CMD6_WRITE_BYTE_SHIFT) /* Change the command set */
+# define MMCSD_CMD6_MODE_SET_BITS ((uint32_t)0x01 <<
MMCSD_CMD6_WRITE_BYTE_SHIFT) /* Set bits which are 1 in value */
+# define MMCSD_CMD6_MODE_CLEAR_BITS ((uint32_t)0x02 <<
MMCSD_CMD6_WRITE_BYTE_SHIFT) /* Clear bits which are 1 in value */
+# define MMCSD_CMD6_MODE_WRITE_BYTE ((uint32_t)0x03 <<
MMCSD_CMD6_WRITE_BYTE_SHIFT) /* Set target to value */
+
+#define MMCSD_CMD6_BUS_WIDTH_SHIFT (8)
+# define MMCSD_CMD6_BUS_WIDTH_1 ((uint32_t)0x00 <<
MMCSD_CMD6_BUS_WIDTH_SHIFT) /* Card is in 1 bit mode */
+# define MMCSD_CMD6_BUS_WIDTH_4 ((uint32_t)0x01 <<
MMCSD_CMD6_BUS_WIDTH_SHIFT) /* Card is in 4 bit mode */
+# define MMCSD_CMD6_CSD_BUS_WIDTH_8 ((uint32_t)0x02 <<
MMCSD_CMD6_BUS_WIDTH_SHIFT) /* Card is in 8 bit mode */
+# define MMCSD_CMD6_DDR_BUS_WIDTH_4 ((uint32_t)0x05 <<
MMCSD_CMD6_BUS_WIDTH_SHIFT) /* Card is in 4 bit DDR mode */
+# define MMCSD_CMD6_DDR_BUS_WIDTH_8 ((uint32_t)0x06 <<
MMCSD_CMD6_BUS_WIDTH_SHIFT) /* Card is in 8 bit DDR mode */
+
/* CMD8 Argument:
* [31:12]: Reserved (shall be set to '0')
* [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)