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

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit f5edfc61dfac34a37c76e23fa3e9e21adbb0dd37
Author: Jukka Laitinen <[email protected]>
AuthorDate: Mon Oct 5 14:47:59 2026 +0300

    arch/arm/imxrt: Support imxrt118x in the uSDHC driver
    
    - Add the missing clock gating macros for imxrt118x
    - Change sw_cd_gpio from int32_t to gpio_pinset_t (64-bits on 118x)
    - Invalidate cache again after the data has been received. Cache might
      be refilled by a prefetch or, in theory, by cpu read touching the same
      cache line - even though the latter should not happen.
    - Map any DMA accesses to/from DTCM to the shadow address window, which
      gives the uSDHC DMA access to the DTCM.
    
    Signed-off-by: Jukka Laitinen <[email protected]>
---
 arch/arm/src/imxrt/imxrt_clockconfig_ver3.h |  3 +++
 arch/arm/src/imxrt/imxrt_usdhc.c            | 35 ++++++++++++++++++++++++-----
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h 
b/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h
index 3d6b19ab9bf..a5c12da6206 100644
--- a/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h
+++ b/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h
@@ -275,6 +275,9 @@ EXTERN const struct clock_configuration_s 
g_initial_clkconfig;
 #define imxrt_clockoff_lpspi5()     imxrt_ccm_gate_on(CCM_LPCG_LPSPI5, false)
 #define imxrt_clockoff_lpspi6()     imxrt_ccm_gate_on(CCM_LPCG_LPSPI6, false)
 
+#define imxrt_clockall_usdhc1()     imxrt_ccm_gate_on(CCM_LPCG_USDHC1, true)
+#define imxrt_clockall_usdhc2()     imxrt_ccm_gate_on(CCM_LPCG_USDHC2, true)
+
 #define imxrt_clockall_usboh3()     imxrt_ccm_gate_on(CCM_LPCG_USB, true)
 #define imxrt_clockoff_usboh3()     imxrt_ccm_gate_on(CCM_LPCG_USB, false)
 #define imxrt_clockrun_usboh3()     imxrt_ccm_gate_on(CCM_LPCG_USB, true)
diff --git a/arch/arm/src/imxrt/imxrt_usdhc.c b/arch/arm/src/imxrt/imxrt_usdhc.c
index d021f2a99e5..9bce9e756ff 100644
--- a/arch/arm/src/imxrt/imxrt_usdhc.c
+++ b/arch/arm/src/imxrt/imxrt_usdhc.c
@@ -49,6 +49,7 @@
 #include "arm_internal.h"
 #include "imxrt_config.h"
 #include "imxrt_gpio.h"
+#include "imxrt_dtcm.h"
 #include "hardware/imxrt_pinmux.h"
 #include "hardware/imxrt_ccm.h"
 #include "imxrt_periphclks.h"
@@ -198,7 +199,7 @@ struct imxrt_dev_s
   void *do_sdio_arg;                  /* arg for SDIO card ISR */
 
   uint32_t addr;                      /* Base address of this instances */
-  uint32_t sw_cd_gpio;                /* If a non USDHCx CD pin is used,
+  gpio_pinset_t sw_cd_gpio;           /* If a non USDHCx CD pin is used,
                                        * this is its GPIO */
   uint32_t cd_invert;                 /* If true invert the CD pin */
 };
@@ -1037,6 +1038,9 @@ static void imxrt_recvdma(struct imxrt_dev_s *priv)
     {
       /* In an aligned case, we have always received all blocks */
 
+      up_invalidate_dcache((uintptr_t)priv->buffer,
+                           (uintptr_t)priv->buffer + priv->remaining);
+
       priv->remaining = 0;
     }
 
@@ -3005,6 +3009,8 @@ static int imxrt_dmarecvsetup(struct sdio_dev_s *dev,
                               uint8_t *buffer, size_t buflen)
 {
   struct imxrt_dev_s *priv = (struct imxrt_dev_s *)dev;
+  uint32_t dma_address;
+  bool ok;
 
   DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
 #if defined(CONFIG_ARCH_HAVE_SDIO_PREFLIGHT)
@@ -3062,19 +3068,28 @@ static int imxrt_dmarecvsetup(struct sdio_dev_s *dev,
   /* Configure the RX DMA */
 
   imxrt_configxfrints(priv, USDHC_DMADONE_INTS);
+
 #if defined(CONFIG_ARMV7M_DCACHE)
   if (priv->unaligned_rx)
     {
-      putreg32((uint32_t) priv->rxbuffer,
-               priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
+      ok = imxrt_dma_address(priv->rxbuffer, priv->blocksize,
+                             &dma_address);
     }
   else
 #endif
     {
-      putreg32((uint32_t) priv->buffer,
-               priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
+      ok = imxrt_dma_address(priv->buffer, buflen, &dma_address);
+    }
+
+  if (!ok)
+    {
+      mcerr("ERROR: buffer %p (len %zu) is not DMA-reachable\n",
+            priv->buffer, buflen);
+      return -EFAULT;
     }
 
+  putreg32(dma_address, priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
+
   /* Sample the register state */
 
   imxrt_sample(priv, SAMPLENDX_AFTER_SETUP);
@@ -3106,6 +3121,7 @@ static int imxrt_dmasendsetup(struct sdio_dev_s *dev,
                               const uint8_t *buffer, size_t buflen)
 {
   struct imxrt_dev_s *priv = (struct imxrt_dev_s *)dev;
+  uint32_t dma_address;
 
   DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
   DEBUGASSERT(((uint32_t) buffer & 3) == 0);
@@ -3136,7 +3152,14 @@ static int imxrt_dmasendsetup(struct sdio_dev_s *dev,
 
   /* Configure the TX DMA */
 
-  putreg32((uint32_t) buffer, priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
+  if (!imxrt_dma_address(buffer, buflen, &dma_address))
+    {
+      mcerr("ERROR: buffer %p (len %zu) is not DMA-reachable\n",
+            buffer, buflen);
+      return -EFAULT;
+    }
+
+  putreg32(dma_address, priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
 
   /* Sample the register state */
 

Reply via email to