This is an automated email from the ASF dual-hosted git repository.

acassis 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 82ab33aed66 arch/arm/src/stm32{h7,f7,l4}: add 4-bit wide bus support 
for MMC/eMMC cards
82ab33aed66 is described below

commit 82ab33aed66671598bcff2b768a7f02a55e8c9a3
Author: DuoYuWang <[email protected]>
AuthorDate: Tue Jul 21 07:29:52 2026 +0800

    arch/arm/src/stm32{h7,f7,l4}: add 4-bit wide bus support for MMC/eMMC cards
    
    The STM32H7, STM32F7, STM32L4 and common STM32 SDIO/SDMMC drivers failed
    to program the WIDBUS bits when switching MMC/eMMC cards to 4-bit mode,
    and the MMC transfer clock presets were hardwired to 1-bit bus width.
    
    Add CLOCK_MMC_TRANSFER_4BIT to the common SDIO clock enum, add 4-bit
    MMC clock presets, and update stm32_widebus() to use modifyreg32/
    sdmmc_modifyreg32 to set the host controller bus width.
    
    Signed-off-by: DuoYuWang <[email protected]>
---
 arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c | 12 ++++++++++++
 arch/arm/src/stm32f7/stm32_sdmmc.c             | 15 ++++++++++++++
 arch/arm/src/stm32h7/stm32_sdmmc.c             | 27 ++++++++++++++++++++++++++
 arch/arm/src/stm32l4/stm32l4_sdmmc.c           | 15 ++++++++++++++
 include/nuttx/sdio.h                           |  5 +++--
 5 files changed, 72 insertions(+), 2 deletions(-)

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 460ce937c48..47b7b7a02c1 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 772e62572bf..debd8c2b704 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 0e713eadb07..f1419f258c8 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 3f1aaef30c8..e0eb3e327b8 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 48b5ff66e52..2a8904f2f75 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

Reply via email to