diff --git a/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c index 460ce937c489e..47b7b7a02c14a 100644 --- a/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c @@ -165,6 +165,8 @@ SDIO_CLKCR_WIDBUS_D1) #define SDIO_CLKCR_MMCXFR (SDIO_MMCXFR_CLKDIV | SDIO_CLKCR_EDGE | \ SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLKCR_MMCXFR4 (SDIO_MMCXFR_CLKDIV | SDIO_CLKCR_EDGE | \ + SDIO_CLKCR_WIDBUS_D4) #define SDIO_CLCKR_SDXFR (SDIO_SDXFR_CLKDIV | SDIO_CLKCR_EDGE | \ SDIO_CLKCR_WIDBUS_D1) #define SDIO_CLCKR_SDWIDEXFR (SDIO_SDXFR_CLKDIV | SDIO_CLKCR_EDGE | \ @@ -1734,7 +1736,11 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev) static void stm32_widebus(struct sdio_dev_s *dev, bool wide) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t widbus = wide ? SDIO_CLKCR_WIDBUS_D4 : SDIO_CLKCR_WIDBUS_D1; + priv->widebus = wide; + + modifyreg32(STM32_SDIO_CLKCR, SDIO_CLKCR_WIDBUS_MASK, widbus); } /**************************************************************************** @@ -1777,6 +1783,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate) clckr = (SDIO_CLKCR_MMCXFR | SDIO_CLKCR_CLKEN); break; + /* Enable in MMC wide (4-bit) operation clocking */ + + case CLOCK_MMC_TRANSFER_4BIT: + clckr = (SDIO_CLKCR_MMCXFR4 | SDIO_CLKCR_CLKEN); + break; + /* SD normal operation clocking (wide 4-bit mode) */ case CLOCK_SD_TRANSFER_4BIT: diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 772e62572bf4f..debd8c2b7044f 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -204,6 +204,9 @@ #define STM32_SDMMC_CLKCR_MMCXFR (STM32_SDMMC_MMCXFR_CLKDIV | \ STM32_SDMMC_CLKCR_EDGE | \ STM32_SDMMC_CLKCR_WIDBUS_D1) +#define STM32_SDMMC_CLKCR_MMCXFR4 (STM32_SDMMC_MMCXFR_CLKDIV | \ + STM32_SDMMC_CLKCR_EDGE | \ + STM32_SDMMC_CLKCR_WIDBUS_D4) #ifdef STM32_SDMMC_SDXFR_BYPCLKDIV # define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_CLKCR_BYPASS | \ @@ -1991,7 +1994,13 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev) static void stm32_widebus(struct sdio_dev_s *dev, bool wide) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t widbus = wide ? STM32_SDMMC_CLKCR_WIDBUS_D4 : + STM32_SDMMC_CLKCR_WIDBUS_D1; + priv->widebus = wide; + + sdmmc_modifyreg32(priv, STM32_SDMMC_CLKCR_OFFSET, + STM32_SDMMC_CLKCR_WIDBUS_MASK, widbus); } /**************************************************************************** @@ -2035,6 +2044,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate) clckr = (STM32_SDMMC_CLKCR_MMCXFR | STM32_SDMMC_CLKCR_CLKEN); break; + /* Enable in MMC wide (4-bit) operation clocking */ + + case CLOCK_MMC_TRANSFER_4BIT: + clckr = (STM32_SDMMC_CLKCR_MMCXFR4 | STM32_SDMMC_CLKCR_CLKEN); + break; + /* SD normal operation clocking (wide 4-bit mode) */ case CLOCK_SD_TRANSFER_4BIT: diff --git a/arch/arm/src/stm32h7/stm32_sdmmc.c b/arch/arm/src/stm32h7/stm32_sdmmc.c index 0e713eadb0795..f1419f258c87c 100644 --- a/arch/arm/src/stm32h7/stm32_sdmmc.c +++ b/arch/arm/src/stm32h7/stm32_sdmmc.c @@ -210,6 +210,10 @@ STM32_SDMMC_CLKCR_EDGE | \ STM32_SDMMC_CLKCR_PWRSAV | \ STM32_SDMMC_CLKCR_WIDBUS_D1) +#define STM32_SDMMC_CLKCR_MMCXFR4 (STM32_SDMMC_MMCXFR_CLKDIV | \ + STM32_SDMMC_CLKCR_EDGE | \ + STM32_SDMMC_CLKCR_PWRSAV | \ + STM32_SDMMC_CLKCR_WIDBUS_D4) #define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_SDXFR_CLKDIV | \ STM32_SDMMC_CLKCR_EDGE | \ STM32_SDMMC_CLKCR_PWRSAV | \ @@ -2045,7 +2049,24 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev) static void stm32_widebus(struct sdio_dev_s *dev, bool wide) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t regval; + priv->widebus = wide; + + regval = sdmmc_getreg32(priv, STM32_SDMMC_CLKCR_OFFSET); + regval &= ~STM32_SDMMC_CLKCR_WIDBUS_MASK; + + if (wide) + { + regval |= STM32_SDMMC_CLKCR_WIDBUS_D4; + regval &= ~STM32_SDMMC_CLKCR_PWRSAV; + } + else + { + regval |= STM32_SDMMC_CLKCR_WIDBUS_D1; + } + + sdmmc_putreg32(priv, regval, STM32_SDMMC_CLKCR_OFFSET); } /**************************************************************************** @@ -2089,6 +2110,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate) clckr = STM32_SDMMC_CLKCR_MMCXFR; break; + /* Enable in MMC wide (4-bit) operation clocking */ + + case CLOCK_MMC_TRANSFER_4BIT: + clckr = STM32_SDMMC_CLKCR_MMCXFR4; + break; + /* SD normal operation clocking (wide 4-bit mode) */ case CLOCK_SD_TRANSFER_4BIT: diff --git a/arch/arm/src/stm32l4/stm32l4_sdmmc.c b/arch/arm/src/stm32l4/stm32l4_sdmmc.c index 3f1aaef30c862..e0eb3e327b85a 100644 --- a/arch/arm/src/stm32l4/stm32l4_sdmmc.c +++ b/arch/arm/src/stm32l4/stm32l4_sdmmc.c @@ -155,6 +155,9 @@ #define STM32_SDMMC_CLKCR_MMCXFR (STM32_SDMMC_MMCXFR_CLKDIV | \ STM32_SDMMC_CLKCR_EDGE | \ STM32_SDMMC_CLKCR_WIDBUS_D1) +#define STM32_SDMMC_CLKCR_MMCXFR4 (STM32_SDMMC_MMCXFR_CLKDIV | \ + STM32_SDMMC_CLKCR_EDGE | \ + STM32_SDMMC_CLKCR_WIDBUS_D4) #define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_SDXFR_CLKDIV | \ STM32_SDMMC_CLKCR_EDGE | \ STM32_SDMMC_CLKCR_WIDBUS_D1) @@ -1786,7 +1789,13 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev) static void stm32_widebus(struct sdio_dev_s *dev, bool wide) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t widbus = wide ? STM32_SDMMC_CLKCR_WIDBUS_D4 : + STM32_SDMMC_CLKCR_WIDBUS_D1; + priv->widebus = wide; + + sdmmc_modifyreg32(priv, STM32_SDMMC_CLKCR_OFFSET, + STM32_SDMMC_CLKCR_WIDBUS_MASK, widbus); } /**************************************************************************** @@ -1830,6 +1839,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate) clckr = (STM32_SDMMC_CLKCR_MMCXFR | STM32_SDMMC_CLKCR_CLKEN); break; + /* Enable in MMC wide (4-bit) operation clocking */ + + case CLOCK_MMC_TRANSFER_4BIT: + clckr = (STM32_SDMMC_CLKCR_MMCXFR4 | STM32_SDMMC_CLKCR_CLKEN); + break; + /* SD normal operation clocking (wide 4-bit mode) */ case CLOCK_SD_TRANSFER_4BIT: diff --git a/include/nuttx/sdio.h b/include/nuttx/sdio.h index 48b5ff66e5276..2a8904f2f75f1 100644 --- a/include/nuttx/sdio.h +++ b/include/nuttx/sdio.h @@ -942,9 +942,10 @@ enum sdio_clock_e { CLOCK_SDIO_DISABLED = 0, /* Clock is disabled */ CLOCK_IDMODE, /* Initial ID mode clocking (<400KHz) */ - CLOCK_MMC_TRANSFER, /* MMC normal operation clocking */ + CLOCK_MMC_TRANSFER, /* MMC normal operation clocking (narrow 1-bit mode) */ CLOCK_SD_TRANSFER_1BIT, /* SD normal operation clocking (narrow 1-bit mode) */ - CLOCK_SD_TRANSFER_4BIT /* SD normal operation clocking (wide 4-bit mode) */ + CLOCK_SD_TRANSFER_4BIT, /* SD normal operation clocking (wide 4-bit mode) */ + CLOCK_MMC_TRANSFER_4BIT /* MMC normal operation clocking (wide 4-bit mode) */ }; /* Event set. A uint8_t is big enough to hold a set of 8-events. If more